summaryrefslogtreecommitdiffstats
path: root/sw/qa/extras/layout/layout.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/qa/extras/layout/layout.cxx')
-rw-r--r--sw/qa/extras/layout/layout.cxx3726
1 files changed, 3726 insertions, 0 deletions
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
new file mode 100644
index 0000000000..668f61f990
--- /dev/null
+++ b/sw/qa/extras/layout/layout.cxx
@@ -0,0 +1,3726 @@
+/* -*- 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 <comphelper/propertysequence.hxx>
+#include <vcl/scheduler.hxx>
+#include <svx/svddef.hxx>
+
+#include <fmtanchr.hxx>
+#include <fmtfsize.hxx>
+#include <fmtcntnt.hxx>
+#include <wrtsh.hxx>
+#include <unotxdoc.hxx>
+#include <rootfrm.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <unoframe.hxx>
+
+/// Test to assert layout / rendering result of Writer.
+class SwLayoutWriter : public SwModelTestBase
+{
+public:
+ SwLayoutWriter()
+ : SwModelTestBase("/sw/qa/extras/layout/data/")
+ {
+ }
+
+protected:
+ void CheckRedlineFootnotesHidden();
+ void CheckRedlineSectionsHidden();
+};
+
+// this is a member because our test classes have protected members :(
+void SwLayoutWriter::CheckRedlineFootnotesHidden()
+{
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr, "24");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "foaz");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[2]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[2]"_ostr,
+ "expand"_ostr, "2");
+ assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "13");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "ac");
+ assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[2]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "16");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "2");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "mo");
+}
+
+void SwLayoutWriter::CheckRedlineSectionsHidden()
+{
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr, "12");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "folah");
+ assertXPath(pXmlDoc, "/root/page[1]/body/section[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "20");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/body/section[1]/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/body/section[1]/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "folah");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf156077)
+{
+ createSwDoc("s4_min2.fodt");
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of pages does not match!", 3, getPages());
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/anchored/fly"_ostr, 3);
+ assertXPath(pXmlDoc, "/root/page[2]/anchored/fly"_ostr, 1);
+ // this was 0, the at-page anchored flys were not displayed
+ assertXPath(pXmlDoc, "/root/page[3]/anchored/fly"_ostr, 3);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testRedlineFootnotes)
+{
+ createSwDoc("redline_footnotes.odt");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc());
+ SwRootFrame* pLayout(pDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+
+ // verify after load
+ CheckRedlineFootnotesHidden();
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[2]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[2]"_ostr,
+ "expand"_ostr, "2");
+
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "a");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[3]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[3]"_ostr,
+ "portion"_ostr, "c");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "2");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "3");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "ar");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[3]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[3]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "3");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[3]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[3]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "ghi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "4");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion[2]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion[2]"_ostr,
+ "expand"_ostr, "5");
+
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[4]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[4]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "4");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[4]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[4]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "jkl");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[5]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[5]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "5");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[5]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[5]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "m");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[5]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[5]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "n");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[5]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[3]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[5]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[3]"_ostr,
+ "portion"_ostr, "o");
+
+ // verify after hide
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ CheckRedlineFootnotesHidden();
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf136588)
+{
+ createSwDoc("tdf136588.docx");
+ auto pXMLLayoutDump = parseLayoutDump();
+ CPPUNIT_ASSERT(pXMLLayoutDump);
+
+ //there was a bad line break before, the correct break layout is this:
+ assertXPath(pXMLLayoutDump, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout[2]"_ostr,
+ "portion"_ostr, "effectively by modern-day small to ");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testRedlineFlysInBody)
+{
+ createSwDoc();
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc());
+ SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+ SwRootFrame* pLayout(pWrtShell->GetLayout());
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ pWrtShell->Insert("foo");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("bar");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("baz");
+ SfxItemSet flySet(pDoc->GetAttrPool(),
+ svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
+ SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
+ pWrtShell->StartOfSection(false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ flySet.Put(anchor);
+ SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
+ flySet.Put(size); // set a size, else we get 1 char per line...
+ SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
+ CPPUNIT_ASSERT(pFly != nullptr);
+ // move inside fly
+ pWrtShell->GotoFly(pFly->GetName(), FLYCNTTYPE_FRM, /*bSelFrame=*/false);
+ pWrtShell->Insert("abc");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("def");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("ghi");
+
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ // delete redline inside fly
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 8, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ pWrtShell->SttEndDoc(true); // note: SttDoc actually moves to start of fly?
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 7, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor.SetAnchor(&pos);
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "14");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foaz");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "6");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "ahi");
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "a");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "bc");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ }
+
+ // anchor to 2nd (deleted) paragraph
+ pWrtShell->StartOfSection();
+ pWrtShell->Down(false, 1);
+ anchor.SetType(RndStdIds::FLY_AT_CHAR);
+ anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor.SetAnchor(&pos);
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "14");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foaz");
+
+ // hide: no anchored object shown
+ assertXPath(pXmlDoc, "//anchored"_ostr, 0);
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "a");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "bc");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ }
+
+ // anchor to 3rd paragraph
+ pWrtShell->EndOfSection();
+ anchor.SetType(RndStdIds::FLY_AT_CHAR);
+ anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor.SetAnchor(&pos);
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "14");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foaz");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "6");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "ahi");
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "a");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "bc");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf134272)
+{
+ createSwDoc("tdf134472.odt");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/header/txt[2]/infos/bounds"_ostr, "height"_ostr, "843");
+ assertXPath(pXmlDoc, "/root/page[1]/header/txt[2]/infos/bounds"_ostr, "bottom"_ostr, "2819");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestNestedTableMoveFwd)
+{
+ createSwDoc("tabellen_test_windows_1.odt");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ // the row with the nested table should not be split but be the first row on page 2
+ assertXPathContent(pXmlDoc, "/root/page[1]/body/tab[1]/row[last()]/cell[1]/txt[1]"_ostr,
+ "Tabelle 1");
+ assertXPathContent(pXmlDoc,
+ "/root/page[2]/body/tab[1]/row[1]/cell[1]/tab[1]/row[1]/cell[1]/txt"_ostr,
+ "Tabelle 2");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf136613)
+{
+ createSwDoc("tdf136613.docx");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+
+ //get the flys and the root frame
+ const auto vFlyFormats = pDoc->GetFlyFrameFormats(FLYCNTTYPE_ALL, true);
+ const auto vFrames = pDoc->GetAllLayouts();
+
+ CPPUNIT_ASSERT(!vFrames.empty());
+ CPPUNIT_ASSERT(!vFlyFormats.empty());
+
+ //get the page frame from the root
+ SwFrame* pPageFrame = vFrames[0]->Lower();
+ CPPUNIT_ASSERT(pPageFrame);
+
+ //get the rectangle of the page
+ const SwRect& rPageRect = pPageFrame->getFrameArea();
+
+ //check the flys and...
+ for (auto pFlyFormat : vFlyFormats)
+ {
+ //...the rectangle of the fly location...
+ const SwRect& rRect = pFlyFormat->FindLayoutRect();
+ CPPUNIT_ASSERT(!rRect.IsEmpty());
+
+ //...if it is on the page. This will fail if not.
+ CPPUNIT_ASSERT_MESSAGE("The pictures are outside the page!", rPageRect.Contains(rRect));
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf88496)
+{
+ createSwDoc("tdf88496.docx");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ // This was 4, table fallback "switch off repeating header" started on a new page
+ assertXPath(pXmlDoc, "/root/page"_ostr, 3);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testRedlineFlysInHeader)
+{
+ createSwDoc();
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc());
+ SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+ SwRootFrame* pLayout(pWrtShell->GetLayout());
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ pWrtShell->ChangeHeaderOrFooter(u"Default Page Style", /*bHeader*/ true, /*bOn*/ true, false);
+ CPPUNIT_ASSERT(
+ pWrtShell
+ ->IsInHeaderFooter()); // assume this is supposed to put cursor in the new header...
+ pWrtShell->Insert("foo");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("bar");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("baz");
+ SfxItemSet flySet(pDoc->GetAttrPool(),
+ svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
+ SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
+ pWrtShell->StartOfSection(false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ flySet.Put(anchor);
+ SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
+ flySet.Put(size); // set a size, else we get 1 char per line...
+ SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
+ CPPUNIT_ASSERT(pFly != nullptr);
+ // move inside fly
+ pWrtShell->GotoFly(pFly->GetName(), FLYCNTTYPE_FRM, /*bSelFrame=*/false);
+ pWrtShell->Insert("abc");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("def");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("ghi");
+
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ // delete redline inside fly
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 8, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ pWrtShell->GotoHeaderText();
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 7, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor.SetAnchor(&pos);
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "length"_ostr, "0");
+ assertXPath(pXmlDoc, "/root/page[1]/header/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "6");
+ assertXPath(pXmlDoc, "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc, "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "portion"_ostr, "foaz");
+ assertXPath(pXmlDoc, "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "11");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "portion"_ostr, "ahi");
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "length"_ostr, "0");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "a");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "bc");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ }
+
+ // anchor to 2nd (deleted) paragraph
+ pWrtShell->StartOfSection();
+ pWrtShell->Down(false, 1);
+ anchor.SetType(RndStdIds::FLY_AT_CHAR);
+ anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor.SetAnchor(&pos);
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ // now the frame has no Text portion? not sure why it's a 0-length one first and now none?
+ // assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]", "type", "PortionType::Para");
+ // assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]", "length", "0");
+ assertXPath(pXmlDoc, "/root/page[1]/header/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "6");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foaz");
+
+ // hide: no anchored object shown
+ assertXPath(pXmlDoc, "//anchored"_ostr, 0);
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "length"_ostr, "0");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "a");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "bc");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ }
+
+ // anchor to 3rd paragraph
+ pWrtShell->EndOfSection();
+ anchor.SetType(RndStdIds::FLY_AT_CHAR);
+ anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor.SetAnchor(&pos);
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "length"_ostr, "0");
+ assertXPath(pXmlDoc, "/root/page[1]/header/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "6");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foaz");
+ assertXPath(pXmlDoc, "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "11");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "ahi");
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "length"_ostr, "0");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "a");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "bc");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/header/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ }
+}
+
+#if !defined(MACOSX)
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf150606)
+{
+ createSwDoc("tdf150606-1-min.odt");
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+ assertXPath(pXmlDoc, "/root/page[1]/body/section/column[1]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[1]/body/section/column[2]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[1]/body/section/column"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page[2]/body/section/column[1]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[2]/body/section/column[2]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[2]/body/section/column"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page[3]/body/section/column[1]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[3]/body/section/column[2]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[3]/body/section/column"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page[4]/body/section/column[1]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[4]/body/section/column[2]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[4]/body/section/column"_ostr, 2);
+ // on page 5 the table is split across balanced columns
+ assertXPath(pXmlDoc, "/root/page[5]/body/section/column[1]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[5]/body/section/column[2]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[5]/body/section/column"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page"_ostr, 5);
+
+ pWrtShell->Down(false, 1);
+ dispatchCommand(mxComponent, ".uno:DeleteTable", {});
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ assertXPath(pXmlDoc, "/root/page[1]/body/section/column/body/tab"_ostr, 0);
+ assertXPath(pXmlDoc, "/root/page"_ostr, 1);
+
+ pWrtShell->Undo();
+ Scheduler::ProcessEventsToIdle();
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ assertXPath(pXmlDoc, "/root/page[1]/body/section/column[1]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[1]/body/section/column[2]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[1]/body/section/column"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page[2]/body/section/column[1]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[2]/body/section/column[2]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[2]/body/section/column"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page[3]/body/section/column[1]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[3]/body/section/column[2]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[3]/body/section/column"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page[4]/body/section/column[1]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[4]/body/section/column[2]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[4]/body/section/column"_ostr, 2);
+ // on page 5 the table is split across balanced columns
+ // (problem was that there were empty pages and table was on page 10)
+ assertXPath(pXmlDoc, "/root/page[5]/body/section/column[1]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[5]/body/section/column[2]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[5]/body/section/column"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page"_ostr, 5);
+}
+#endif
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf152983)
+{
+ //just care it doesn't crash/assert
+ createSwDoc("tdf152983-1-min.docx");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf137025)
+{
+ // Check the padding of the textbox
+ createSwDoc("tdf137025.docx");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ // Check the layout xml
+ // SDRATTR_TEXT_LEFTDIST
+ assertXPath(pXmlDoc,
+ "/root/page/body/txt/anchored/SwAnchoredDrawObject/SdrObject"
+ "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item"
+ "[@whichId='"
+ + OString::number(SDRATTR_TEXT_LEFTDIST) + "']",
+ "value"_ostr, "567");
+ // SDRATTR_TEXT_RIGHTDIST
+ assertXPath(pXmlDoc,
+ "/root/page/body/txt/anchored/SwAnchoredDrawObject/SdrObject"
+ "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item"
+ "[@whichId='"
+ + OString::number(SDRATTR_TEXT_RIGHTDIST) + "']",
+ "value"_ostr, "1134");
+ // SDRATTR_TEXT_UPPERDIST
+ assertXPath(pXmlDoc,
+ "/root/page/body/txt/anchored/SwAnchoredDrawObject/SdrObject"
+ "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item"
+ "[@whichId='"
+ + OString::number(SDRATTR_TEXT_UPPERDIST) + "']",
+ "value"_ostr, "1701");
+ // SDRATTR_TEXT_LOWERDIST
+ assertXPath(pXmlDoc,
+ "/root/page/body/txt/anchored/SwAnchoredDrawObject/SdrObject"
+ "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item"
+ "[@whichId='"
+ + OString::number(SDRATTR_TEXT_LOWERDIST) + "']",
+ "value"_ostr, "2268");
+
+ // Check the textbox-shape import too
+ auto xShp = getShape(1);
+ CPPUNIT_ASSERT(xShp);
+
+ uno::Reference<beans::XPropertySet> xShapeProps(xShp, uno::UNO_QUERY);
+
+ SwFrameFormat* pFrameFormat = SwTextBoxHelper::getOtherTextBoxFormat(xShp);
+ CPPUNIT_ASSERT(pFrameFormat);
+
+ // The shape has these values to copy to the associated text frame after modification::
+ const tools::Long nLPaddng
+ = xShapeProps->getPropertyValue("TextLeftDistance").get<tools::Long>();
+ const tools::Long nRPaddng
+ = xShapeProps->getPropertyValue("TextRightDistance").get<tools::Long>();
+ const tools::Long nTPaddng
+ = xShapeProps->getPropertyValue("TextUpperDistance").get<tools::Long>();
+ const tools::Long nBPaddng
+ = xShapeProps->getPropertyValue("TextLowerDistance").get<tools::Long>();
+
+ CPPUNIT_ASSERT_EQUAL(tools::Long(1000), nLPaddng);
+ CPPUNIT_ASSERT_EQUAL(tools::Long(2000), nRPaddng);
+ CPPUNIT_ASSERT_EQUAL(tools::Long(3000), nTPaddng);
+ CPPUNIT_ASSERT_EQUAL(tools::Long(4001), nBPaddng);
+
+ // TODO: modify shape distance via UNO with text frame synchronization
+ // Check the textbox as well:
+ auto xTxFrm = SwXTextFrame::CreateXTextFrame(*pFrameFormat->GetDoc(), pFrameFormat);
+ CPPUNIT_ASSERT(xTxFrm);
+
+ const tools::Long nFrameLeftPaddng
+ = xTxFrm->getPropertyValue("LeftBorderDistance").get<tools::Long>();
+ const tools::Long nFrameRightPaddng
+ = xTxFrm->getPropertyValue("RightBorderDistance").get<tools::Long>();
+ const tools::Long nFrameTopPaddng
+ = xTxFrm->getPropertyValue("TopBorderDistance").get<tools::Long>();
+ const tools::Long nFrameBottomPaddng
+ = xTxFrm->getPropertyValue("BottomBorderDistance").get<tools::Long>();
+
+ // Check if the shape and frame have different setting
+ CPPUNIT_ASSERT_EQUAL(nLPaddng, nFrameLeftPaddng);
+ CPPUNIT_ASSERT_EQUAL(nRPaddng, nFrameRightPaddng);
+ CPPUNIT_ASSERT_EQUAL(nTPaddng, nFrameTopPaddng);
+ CPPUNIT_ASSERT_EQUAL(nBPaddng, nFrameBottomPaddng);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testRedlineFlysInFootnote)
+{
+ createSwDoc();
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc());
+ SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+ SwRootFrame* pLayout(pWrtShell->GetLayout());
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ pWrtShell->InsertFootnote("");
+ CPPUNIT_ASSERT(pWrtShell->IsCursorInFootnote());
+
+ SfxItemSet flySet(pDoc->GetAttrPool(),
+ svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
+ SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
+ flySet.Put(size); // set a size, else we get 1 char per line...
+ SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
+ anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ flySet.Put(anchor);
+ // first fly is in first footnote that will be deleted
+ /* SwFrameFormat const* pFly1 =*/pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
+ pWrtShell->Insert("quux");
+
+ pWrtShell->SttEndDoc(false);
+
+ pWrtShell->InsertFootnote("");
+ CPPUNIT_ASSERT(pWrtShell->IsCursorInFootnote());
+ pWrtShell->Insert("foo");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("bar");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("baz");
+
+ pWrtShell->StartOfSection(false);
+ CPPUNIT_ASSERT(pWrtShell->IsCursorInFootnote());
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ flySet.Put(anchor);
+ // second fly is in second footnote that is not deleted
+ SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
+ CPPUNIT_ASSERT(pFly != nullptr);
+ // move inside fly
+ pWrtShell->GotoFly(pFly->GetName(), FLYCNTTYPE_FRM, /*bSelFrame=*/false);
+ pWrtShell->Insert("abc");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("def");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("ghi");
+
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ // delete redline inside fly
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 8, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ // pWrtShell->GotoFlyAnchor(); // sigh... why, now we're in the body...
+ pWrtShell->SttEndDoc(false);
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ pWrtShell->GotoFootnoteText();
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 7, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+ pWrtShell->EndSelect(); // ?
+ // delete first footnote
+ pWrtShell->SttEndDoc(true);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor.SetAnchor(&pos);
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "25");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/"
+ "child::*[@type='PortionType::Footnote']"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/"
+ "child::*[@type='PortionType::Footnote']"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "7");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "17");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "ahi");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[2]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[2]"_ostr,
+ "expand"_ostr, "2");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "quux");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "a");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "bc");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/anchored/fly[1]/txt[2]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/anchored/fly[1]/txt[2]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "2");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ }
+
+ // anchor to 2nd (deleted) paragraph
+ pWrtShell->SttEndDoc(false);
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ pWrtShell->GotoFootnoteText();
+ pWrtShell->Down(false, 1);
+ anchor.SetType(RndStdIds::FLY_AT_CHAR);
+ anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor.SetAnchor(&pos);
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "25");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "7");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+
+ // hide: no anchored object shown
+ assertXPath(pXmlDoc, "//anchored"_ostr, 0);
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[2]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[2]"_ostr,
+ "expand"_ostr, "2");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "quux");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "2");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "a");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "bc");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/anchored/fly[1]/txt[2]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/anchored/fly[1]/txt[2]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ }
+
+ // anchor to 3rd paragraph
+ pWrtShell->EndOfSection();
+ pWrtShell->SttEndDoc(false);
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ pWrtShell->GotoFootnoteText();
+ pWrtShell->EndOfSection();
+ anchor.SetType(RndStdIds::FLY_AT_CHAR);
+ anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor.SetAnchor(&pos);
+ pDoc->SetAttr(anchor, *const_cast<SwFrameFormat*>(pFly));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "25");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "7");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "17");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "ahi");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/"
+ "child::*[@type='PortionType::Footnote'][1]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/"
+ "child::*[@type='PortionType::Footnote'][1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/"
+ "child::*[@type='PortionType::Footnote'][2]"_ostr,
+ "type"_ostr, "PortionType::Footnote");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/"
+ "child::*[@type='PortionType::Footnote'][2]"_ostr,
+ "expand"_ostr, "2");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "quux");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[1]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "1");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "type"_ostr, "PortionType::FootnoteNum");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]"_ostr,
+ "expand"_ostr, "2");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "a");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "bc");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/anchored/fly[1]/txt[2]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/anchored/fly[1]/txt[2]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/ftncont/ftn[2]/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf143239)
+{
+ createSwDoc("tdf143239-1-min.odt");
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+ // These are unstable on macOS and Win64 builds,
+ // so only test that they restore original values for now
+ OUString p2txt1Left, p2txt2Left, p3txt1Left;
+
+ {
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[2]/body/txt[1]/anchored/fly"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[2]/body/txt[1]/anchored/fly[1]/infos/bounds"_ostr,
+ "top"_ostr, "18540");
+ p2txt1Left = getXPath(
+ pXmlDoc, "/root/page[2]/body/txt[1]/anchored/fly[1]/infos/bounds"_ostr, "left"_ostr);
+ assertXPath(pXmlDoc, "/root/page[2]/body/txt[2]/anchored/fly"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[2]/body/txt[2]/anchored/fly[1]/infos/bounds"_ostr,
+ "top"_ostr, "23894");
+ p2txt2Left = getXPath(
+ pXmlDoc, "/root/page[2]/body/txt[2]/anchored/fly[1]/infos/bounds"_ostr, "left"_ostr);
+ assertXPath(pXmlDoc, "/root/page[3]/body/txt[1]/anchored/fly"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[3]/body/txt[1]/anchored/fly[1]/infos/bounds"_ostr,
+ "top"_ostr, "35662");
+ p3txt1Left = getXPath(
+ pXmlDoc, "/root/page[3]/body/txt[1]/anchored/fly[1]/infos/bounds"_ostr, "left"_ostr);
+ assertXPath(pXmlDoc, "/root/page"_ostr, 3);
+ discardDumpedLayout();
+ }
+
+ pWrtShell->SelAll();
+ pWrtShell->Delete();
+ pWrtShell->Undo();
+ Scheduler::ProcessEventsToIdle();
+
+ {
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ // now the 1st fly was on page 1, and the fly on page 2 was the 2nd one
+ assertXPath(pXmlDoc, "/root/page[2]/body/txt[1]/anchored/fly"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[2]/body/txt[1]/anchored/fly[1]/infos/bounds"_ostr,
+ "top"_ostr, "18540");
+ assertXPath(pXmlDoc, "/root/page[2]/body/txt[1]/anchored/fly[1]/infos/bounds"_ostr,
+ "left"_ostr, p2txt1Left);
+ assertXPath(pXmlDoc, "/root/page[2]/body/txt[2]/anchored/fly"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[2]/body/txt[2]/anchored/fly[1]/infos/bounds"_ostr,
+ "top"_ostr, "23894");
+ assertXPath(pXmlDoc, "/root/page[2]/body/txt[2]/anchored/fly[1]/infos/bounds"_ostr,
+ "left"_ostr, p2txt2Left);
+ assertXPath(pXmlDoc, "/root/page[3]/body/txt[1]/anchored/fly"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[3]/body/txt[1]/anchored/fly[1]/infos/bounds"_ostr,
+ "top"_ostr, "35662");
+ assertXPath(pXmlDoc, "/root/page[3]/body/txt[1]/anchored/fly[1]/infos/bounds"_ostr,
+ "left"_ostr, p3txt1Left);
+ assertXPath(pXmlDoc, "/root/page"_ostr, 3);
+ discardDumpedLayout();
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTableOverlapFooterFly)
+{
+ // Load a document that has a fly anchored in the footer.
+ // It also has a table which initially overlaps with the fly, but then moves to the next page.
+ createSwDoc("footer-fly-table.fodt");
+ xmlDocUniquePtr pLayout = parseLayoutDump();
+ // no fly portions, was: 8
+ assertXPath(pLayout,
+ "/root/page[2]/body/tab[1]/row[5]/cell[5]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwFixPortion[@type='PortionType::Fly'][@type='PortionType::Fly']"_ostr,
+ 0);
+ // one line break, was: 5
+ assertXPath(pLayout,
+ "/root/page[2]/body/tab[1]/row[5]/cell[5]/txt[1]/SwParaPortion/SwLineLayout"_ostr,
+ 1);
+ // one text portion, was: 1
+ assertXPath(
+ pLayout,
+ "/root/page[2]/body/tab[1]/row[5]/cell[5]/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion"_ostr,
+ 1);
+ assertXPath(
+ pLayout,
+ "/root/page[2]/body/tab[1]/row[5]/cell[5]/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion"_ostr,
+ "portion"_ostr, "Abc def ghi jkl mno pqr stu vwx yz.");
+ // height was: 1517
+ // tdf#134782 height was: 379
+ assertXPath(pLayout, "/root/page[2]/body/tab[1]/row[5]/cell[5]/txt[1]/infos/bounds"_ostr,
+ "height"_ostr, "253");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf134277)
+{
+ createSwDoc("tdf134277.docx");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ SwDocShell* pShell = pDoc->GetDocShell();
+
+ std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
+ MetafileXmlDump dumper;
+
+ xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ assertXPath(pXmlDoc, "/metafile/push/push/push/layoutmode[2]"_ostr, 0);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf116486)
+{
+ createSwDoc("tdf116486.docx");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ OUString aTop = parseDump(
+ "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/child::*[@type='PortionType::Fly']"_ostr,
+ "height"_ostr);
+ CPPUNIT_ASSERT_EQUAL(OUString("4006"), aTop);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf142080)
+{
+ // this caused an infinite loop
+ createSwDoc("fdo43573-2-min.docx");
+
+ xmlDocUniquePtr pLayout = parseLayoutDump();
+ // check the first paragraph on page 9 with its fly; the column was empty too
+ assertXPath(pLayout,
+ "/root/page[9]/body/section[1]/column[1]/body/txt[1]/SwParaPortion/SwLineLayout[2]/"
+ "SwLinePortion"_ostr,
+ "portion"_ostr,
+ "De kleur u (rood) in het rechtervlak (R), de kleur r (wit) beneden (D),");
+ SwTwips nPage9Top = getXPath(pLayout, "/root/page[9]/infos/bounds"_ostr, "top"_ostr).toInt32();
+ assertXPath(
+ pLayout,
+ "/root/page[9]/body/section[1]/column[1]/body/txt[1]/anchored/fly[1]/notxt/infos/bounds"_ostr,
+ "top"_ostr, OUString::number(nPage9Top + 1460));
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf152106)
+{
+ // this caused an infinite loop
+ createSwDoc("tdf152106.odt");
+
+ xmlDocUniquePtr pLayout = parseLayoutDump();
+
+ // frame on page 3
+ assertXPath(pLayout, "/root/page[3]/sorted_objs/fly"_ostr, 1);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf128198)
+{
+ createSwDoc("tdf128198-1.docx");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ xmlDocUniquePtr pLayout = parseLayoutDump();
+ // the problem was that line 5 was truncated at "this "
+ // due to the fly anchored in previous paragraph
+ assertXPath(pLayout, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout[5]"_ostr,
+ "portion"_ostr,
+ "to access any service, any time, anywhere. From this perspective, satellite "
+ "boasts some ");
+ assertXPath(pLayout, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout[6]"_ostr,
+ "portion"_ostr, "significant advantages. ");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testNoLineBreakAtSlash)
+{
+ createSwDoc("no-line-break-at-slash.fodt");
+ xmlDocUniquePtr pLayout = parseLayoutDump();
+
+ // the line break was between "Foostrasse 13/c/" and "2"
+ assertXPath(pLayout, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 2);
+ assertXPath(pLayout, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]/child::*"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pLayout, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[2]/child::*[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pLayout, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[2]/child::*[2]"_ostr,
+ "type"_ostr, "PortionType::Blank");
+ assertXPath(pLayout, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[2]/child::*[3]"_ostr,
+ "type"_ostr, "PortionType::Text");
+
+ assertXPath(pLayout, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "portion"_ostr, "Blah blah bla bla bla ");
+ assertXPath(pLayout,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[2]/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "Foostrasse");
+ assertXPath(pLayout,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[2]/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "13/c/2, etc.");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf106153)
+{
+ createSwDoc("tdf106153.docx");
+ xmlDocUniquePtr pDump = parseLayoutDump();
+
+ const sal_Int64 nPageValLeft
+ = getXPath(pDump, "/root/page/infos/bounds"_ostr, "left"_ostr).toInt64();
+ const sal_Int64 nPageValTop
+ = getXPath(pDump, "/root/page/infos/bounds"_ostr, "top"_ostr).toInt64();
+ const sal_Int64 nPageValRight
+ = getXPath(pDump, "/root/page/infos/bounds"_ostr, "right"_ostr).toInt64();
+ const sal_Int64 nPageValBottom
+ = getXPath(pDump, "/root/page/infos/bounds"_ostr, "bottom"_ostr).toInt64();
+
+ const sal_Int64 nShape1ValTop
+ = getXPath(pDump, "/root/page/body/txt/anchored/fly[1]/infos/bounds"_ostr, "top"_ostr)
+ .toInt64();
+ const sal_Int64 nShape2ValLeft
+ = getXPath(pDump, "/root/page/body/txt/anchored/fly[2]/infos/bounds"_ostr, "left"_ostr)
+ .toInt64();
+ const sal_Int64 nShape3ValRight
+ = getXPath(pDump, "/root/page/body/txt/anchored/fly[3]/infos/bounds"_ostr, "right"_ostr)
+ .toInt64();
+ const sal_Int64 nShape4ValBottom
+ = getXPath(pDump, "/root/page/body/txt/anchored/fly[4]/infos/bounds"_ostr, "bottom"_ostr)
+ .toInt64();
+
+ CPPUNIT_ASSERT_MESSAGE("The whole top textbox is inside the page!",
+ nPageValTop > nShape1ValTop);
+ CPPUNIT_ASSERT_MESSAGE("The whole left textbox is inside the page!",
+ nPageValLeft > nShape2ValLeft);
+ CPPUNIT_ASSERT_MESSAGE("The whole right textbox is inside the page!",
+ nPageValRight < nShape3ValRight);
+ CPPUNIT_ASSERT_MESSAGE("The whole bottom textbox is inside the page!",
+ nPageValBottom < nShape4ValBottom);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testRedlineFlysInFlys)
+{
+ createSwDoc();
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc());
+ SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+ SwRootFrame* pLayout(pWrtShell->GetLayout());
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ pWrtShell->Insert("foo");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("bar");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("baz");
+ SfxItemSet flySet(pDoc->GetAttrPool(),
+ svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
+ SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
+ flySet.Put(size); // set a size, else we get 1 char per line...
+ pWrtShell->StartOfSection(false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ SwFormatAnchor anchor1(RndStdIds::FLY_AT_CHAR);
+ anchor1.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ flySet.Put(anchor1);
+ SwFrameFormat const* pFly1 = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
+ CPPUNIT_ASSERT(pFly1 != nullptr);
+ // move inside fly1
+ pWrtShell->GotoFly(pFly1->GetName(), FLYCNTTYPE_FRM, /*bSelFrame=*/false);
+ pWrtShell->Insert("abc");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("def");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("ghi");
+
+ SwFormatAnchor anchor2(RndStdIds::FLY_AT_CHAR);
+ pWrtShell->StartOfSection(false); // start of fly...
+ anchor2.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ flySet.Put(anchor2);
+ SwFrameFormat const* pFly2 = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
+ CPPUNIT_ASSERT(pFly2 != nullptr);
+ // move inside fly2
+ pWrtShell->GotoFly(pFly2->GetName(), FLYCNTTYPE_FRM, /*bSelFrame=*/false);
+ pWrtShell->Insert("jkl");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("mno");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("pqr");
+
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ // delete redline inside fly2
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 8, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ // delete redline inside fly1
+ pWrtShell->GotoFly(pFly1->GetName(), FLYCNTTYPE_FRM, /*bSelFrame=*/false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 7, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ pWrtShell->ClearMark(); // otherwise it refuses to leave the fly...
+ pWrtShell->SttEndDoc(true); // note: SttDoc actually moves to start of fly?
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 7, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor1.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor1.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor1.SetAnchor(&pos);
+ pDoc->SetAttr(anchor1, *const_cast<SwFrameFormat*>(pFly1));
+ anchor2.SetType(RndStdIds::FLY_AT_PARA);
+ pos.nNode = *anchor2.GetAnchorNode();
+ anchor2.SetAnchor(&pos);
+ pDoc->SetAttr(anchor2, *const_cast<SwFrameFormat*>(pFly2));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "19");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "6");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "11");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "jqr");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwFixPortion[1]"_ostr,
+ "type"_ostr,
+ "PortionType::Fly"); // remove???
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLineLayout[1]"_ostr,
+ "type"_ostr, "PortionType::Lay");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLineLayout[1]"_ostr,
+ "portion"_ostr, "abhi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foaz");
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "j");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "kl");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[2]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[2]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "mno");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "p");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "qr");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwFixPortion[1]"_ostr,
+ "type"_ostr,
+ "PortionType::Fly"); // remove???
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "ab");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "c");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ }
+
+ // anchor to 2nd (deleted) paragraph
+ // also, switch the in-fly anchoring to the other fly, for additional fun!
+ pWrtShell->StartOfSection();
+ pWrtShell->Down(false, 1);
+ anchor2.SetType(RndStdIds::FLY_AT_CHAR);
+ anchor2.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ pDoc->SetAttr(anchor2, *const_cast<SwFrameFormat*>(pFly2));
+ pWrtShell->GotoFly(pFly2->GetName(), FLYCNTTYPE_FRM, /*bSelFrame=*/false);
+ pWrtShell->Down(false, 1);
+ anchor1.SetType(RndStdIds::FLY_AT_CHAR);
+ anchor1.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ pDoc->SetAttr(anchor1, *const_cast<SwFrameFormat*>(pFly1));
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor1.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor1.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor1.SetAnchor(&pos);
+ pDoc->SetAttr(anchor1, *const_cast<SwFrameFormat*>(pFly1));
+ anchor2.SetType(RndStdIds::FLY_AT_PARA);
+ pos.nNode = *anchor2.GetAnchorNode();
+ anchor2.SetAnchor(&pos);
+ pDoc->SetAttr(anchor2, *const_cast<SwFrameFormat*>(pFly2));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "19");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foaz");
+
+ // hide: no anchored object shown
+ assertXPath(pXmlDoc, "//anchored"_ostr, 0);
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "j");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "kl");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "ab");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "c");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/anchored[1]/fly[1]/txt[2]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/anchored[1]/fly[1]/txt[2]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwFixPortion[1]"_ostr,
+ "type"_ostr,
+ "PortionType::Fly"); // remove???
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwLineLayout[1]"_ostr,
+ "type"_ostr, "PortionType::Lay");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwLineLayout[1]"_ostr,
+ "portion"_ostr, "mno");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "p");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "qr");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ }
+
+ // anchor to 3rd paragraph
+ pWrtShell->SttEndDoc(false);
+ anchor1.SetType(RndStdIds::FLY_AT_CHAR);
+ anchor1.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ pDoc->SetAttr(anchor1, *const_cast<SwFrameFormat*>(pFly1));
+ pWrtShell->GotoFly(pFly1->GetName(), FLYCNTTYPE_FRM, /*bSelFrame=*/false);
+ pWrtShell->EndOfSection();
+ anchor2.SetType(RndStdIds::FLY_AT_CHAR);
+ anchor2.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ pDoc->SetAttr(anchor2, *const_cast<SwFrameFormat*>(pFly2));
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 1) // secondly, try with different anchor type
+ {
+ anchor1.SetType(RndStdIds::FLY_AT_PARA);
+ SwPosition pos(*anchor1.GetAnchorNode());
+ pos.nContent.Assign(nullptr, 0);
+ anchor1.SetAnchor(&pos);
+ pDoc->SetAttr(anchor1, *const_cast<SwFrameFormat*>(pFly1));
+ anchor2.SetType(RndStdIds::FLY_AT_PARA);
+ pos.nNode = *anchor2.GetAnchorNode();
+ anchor2.SetAnchor(&pos);
+ pDoc->SetAttr(anchor2, *const_cast<SwFrameFormat*>(pFly2));
+ }
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr,
+ "19");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "6");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "11");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "jqr");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwFixPortion[1]"_ostr,
+ "type"_ostr,
+ "PortionType::Fly"); // remove???
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLineLayout[1]"_ostr,
+ "type"_ostr, "PortionType::Lay");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLineLayout[1]"_ostr,
+ "portion"_ostr, "abhi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foaz");
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "ab");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "c");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "j");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/anchored[1]/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "kl");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/anchored[1]/fly[1]/txt[2]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/anchored[1]/fly[1]/txt[2]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "mno");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "p");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/anchored[1]/fly[1]/txt[3]/"
+ "SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "qr");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwFixPortion[1]"_ostr,
+ "type"_ostr,
+ "PortionType::Fly"); // remove???
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testRedlineFlysAtFlys)
+{
+ createSwDoc();
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc());
+ SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+ SwRootFrame* pLayout(pWrtShell->GetLayout());
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ pWrtShell->Insert("foo");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("bar");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("baz");
+ SfxItemSet flySet(pDoc->GetAttrPool(),
+ svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
+ SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
+ flySet.Put(size); // set a size, else we get 1 char per line...
+ pWrtShell->StartOfSection(false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ SwFormatAnchor anchor1(RndStdIds::FLY_AT_CHAR);
+ anchor1.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ flySet.Put(anchor1);
+ SwFrameFormat const* pFly1 = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
+ CPPUNIT_ASSERT(pFly1 != nullptr);
+ // move inside fly1
+ pWrtShell->GotoFly(pFly1->GetName(), FLYCNTTYPE_FRM, /*bSelFrame=*/false);
+ pWrtShell->Insert("abc");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("def");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("ghi");
+
+ SwFormatAnchor anchor2(RndStdIds::FLY_AT_FLY);
+ SwPosition pos(*pFly1->GetContent().GetContentIdx());
+ anchor2.SetAnchor(&pos);
+ flySet.Put(anchor2);
+ SwFrameFormat const* pFly2 = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
+ CPPUNIT_ASSERT(pFly2 != nullptr);
+ // move inside fly2
+ pWrtShell->GotoFly(pFly2->GetName(), FLYCNTTYPE_FRM, /*bSelFrame=*/false);
+ pWrtShell->Insert("jkl");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("mno");
+ pWrtShell->SplitNode(false);
+ pWrtShell->Insert("pqr");
+
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ // delete redline inside fly2
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 8, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ // delete redline inside fly1
+ pWrtShell->GotoFly(pFly1->GetName(), FLYCNTTYPE_FRM, /*bSelFrame=*/false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 7, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ pWrtShell->ClearMark(); // otherwise it refuses to leave the fly...
+ pWrtShell->SttEndDoc(true); // note: SttDoc actually moves to start of fly?
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 7, /*bBasicCall=*/false);
+ pWrtShell->Delete();
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr, "19");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "6");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[1]/merged"_ostr,
+ "paraPropsNodeIndex"_ostr, "11");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "jqr");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwFixPortion[1]"_ostr,
+ "type"_ostr,
+ "PortionType::Fly"); // remove???
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLineLayout[1]"_ostr,
+ "type"_ostr, "PortionType::Lay");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLineLayout[1]"_ostr,
+ "portion"_ostr, "abhi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foaz");
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "j");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "kl");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[2]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[2]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "mno");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "p");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/anchored[1]/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "qr");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwFixPortion[1]"_ostr,
+ "type"_ostr,
+ "PortionType::Fly"); // remove???
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "ab");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "c");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+
+ // anchor to 2nd (deleted) paragraph
+ pWrtShell->StartOfSection();
+ pWrtShell->Down(false, 1);
+ anchor1.SetType(RndStdIds::FLY_AT_CHAR);
+ anchor1.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+ pDoc->SetAttr(anchor1, *const_cast<SwFrameFormat*>(pFly1));
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr, "19");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foaz");
+
+ // hide: no anchored object shown
+ assertXPath(pXmlDoc, "//anchored"_ostr, 0);
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/anchored[1]/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/anchored[1]/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "j");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/anchored[1]/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/anchored[1]/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "kl");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/anchored[1]/fly[1]/txt[2]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/anchored[1]/fly[1]/txt[2]/SwParaPortion/"
+ "SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "mno");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/anchored[1]/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/anchored[1]/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "p");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/anchored[1]/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/anchored[1]/fly[1]/txt[3]/SwParaPortion/"
+ "SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "qr");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwFixPortion[1]"_ostr,
+ "type"_ostr,
+ "PortionType::Fly"); // remove???
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "ab");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "c");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[2]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "def");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[1]"_ostr,
+ "portion"_ostr, "g");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/anchored/fly[1]/txt[3]/SwParaPortion/SwLineLayout/"
+ "SwLinePortion[2]"_ostr,
+ "portion"_ostr, "hi");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "az");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testRedlineSections)
+{
+ createSwDoc("redline_sections.fodt");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc());
+ SwRootFrame* pLayout(pDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+
+ // verify after load
+ CheckRedlineSectionsHidden();
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ // why is this needed explicitly?
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/child::*[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/child::*[2]"_ostr,
+ "portion"_ostr, "o");
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/child::*[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[1]/txt[1]/anchored/fly[1]/txt[1]/SwParaPortion/"
+ "SwLineLayout/child::*[1]"_ostr,
+ "portion"_ostr, "FRAME");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[1]/txt[1]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[1]/txt[1]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[1]/txt[2]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[1]/txt[2]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "portion"_ostr, "baz");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/child::*[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/child::*[2]"_ostr,
+ "portion"_ostr, "lah");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[2]/txt[1]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[2]/txt[1]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[2]/txt[1]/SwParaPortion/SwLineLayout/child::*[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[2]/txt[1]/SwParaPortion/SwLineLayout/child::*[2]"_ostr,
+ "portion"_ostr, "o");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[2]/txt[2]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[2]/txt[2]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "portion"_ostr, "bar");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[2]/txt[3]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[2]/txt[3]/SwParaPortion/SwLineLayout/child::*[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[2]/txt[3]/SwParaPortion/SwLineLayout/child::*[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/section[2]/txt[3]/SwParaPortion/SwLineLayout/child::*[2]"_ostr,
+ "portion"_ostr, "lah");
+
+ // verify after hide
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ // why is this needed explicitly?
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+ discardDumpedLayout();
+ CheckRedlineSectionsHidden();
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TDF69647_images)
+{
+ createSwDoc("tdf69647_images.odt");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of pages does not match!", 2, getPages());
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TDF69647_text)
+{
+ createSwDoc("tdf69647_text.docx");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of pages does not match!", 2, getPages());
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testRedlineTables)
+{
+ createSwDoc("redline_table.fodt");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc());
+ SwRootFrame* pLayout(pDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+
+ // verify after load
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr, "12");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foar");
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ // why is this needed explicitly?
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // show: nothing is merged
+ assertXPath(pXmlDoc, "//merged"_ostr, 0);
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "fo");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "o");
+
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab[1]/row[1]/cell[1]/txt[1]/anchored/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab[1]/row[1]/cell[1]/txt[1]/anchored/fly[1]/txt[1]/"
+ "SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "FRAME");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab[1]/row[1]/cell[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab[1]/row[1]/cell[1]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "aaa");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab[1]/row[2]/cell[2]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab[1]/row[2]/cell[2]/txt[1]/SwParaPortion/SwLineLayout/"
+ "SwParaPortion[1]"_ostr,
+ "portion"_ostr, "ddd");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "b");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "type"_ostr, "PortionType::Text");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[2]"_ostr,
+ "portion"_ostr, "ar");
+
+ // verify after hide
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ // why is this needed explicitly?
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged"_ostr, "paraPropsNodeIndex"_ostr, "12");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "type"_ostr, "PortionType::Para");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]"_ostr,
+ "portion"_ostr, "foar");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf144057)
+{
+ createSwDoc("tdf144057.fodt");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc());
+ SwRootFrame* pLayout(pDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ // show tracked row deletions
+ assertXPath(pXmlDoc, "/root/page"_ostr, 4);
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/body/tab/row[6]/cell/txt/SwParaPortion/SwLineLayout/SwParaPortion"_ostr,
+ "portion"_ostr, "A6");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[2]/body/tab/row[6]/cell/txt/SwParaPortion/SwLineLayout/SwParaPortion"_ostr,
+ "portion"_ostr, "A12");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[3]/body/tab/row[6]/cell/txt/SwParaPortion/SwLineLayout/SwParaPortion"_ostr,
+ "portion"_ostr, "B6");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[4]/body/tab/row[6]/cell/txt/SwParaPortion/SwLineLayout/SwParaPortion"_ostr,
+ "portion"_ostr, "B12");
+
+ // hide tracked table and table row deletions
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // This was 4 (unhidden tracked table and table row deletions)
+ assertXPath(pXmlDoc, "/root/page"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 5);
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/body/tab/row[5]/cell/txt/SwParaPortion/SwLineLayout/SwParaPortion"_ostr,
+ "portion"_ostr, "B12");
+
+ // show tracked table and table row deletions again
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page"_ostr, 4);
+ assertXPath(
+ pXmlDoc,
+ "/root/page[1]/body/tab/row[6]/cell/txt/SwParaPortion/SwLineLayout/SwParaPortion"_ostr,
+ "portion"_ostr, "A6");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[2]/body/tab/row[6]/cell/txt/SwParaPortion/SwLineLayout/SwParaPortion"_ostr,
+ "portion"_ostr, "A12");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[3]/body/tab/row[6]/cell/txt/SwParaPortion/SwLineLayout/SwParaPortion"_ostr,
+ "portion"_ostr, "B6");
+ assertXPath(
+ pXmlDoc,
+ "/root/page[4]/body/tab/row[6]/cell/txt/SwParaPortion/SwLineLayout/SwParaPortion"_ostr,
+ "portion"_ostr, "B12");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf144347)
+{
+ createSwDoc("tdf144057.fodt");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc());
+ SwRootFrame* pLayout(pDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+
+ // enable redlining
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+ pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+
+ // remove first table
+ SwEditShell* const pEditShell(pDoc->GetEditShell());
+ for (int i = 0; i < 12; ++i)
+ pEditShell->AcceptRedline(0);
+
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ // show tracked row deletions
+ assertXPath(pXmlDoc, "/root/page"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab"_ostr, 1);
+
+ // select all the text, including the texts before and after the table
+ // Note: this table contains tracked changes, which was a
+ // problem for the original OOo implementation of track changes,
+ // resulting empty tables after accepting the deletion of these tables.
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:Delete", {});
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // table is deleted with change tracking: it still exists
+ assertXPath(pXmlDoc, "/root/page"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab"_ostr, 1);
+
+ // accept all deletions, removing the table completely
+ while (pEditShell->GetRedlineCount() > 0)
+ pEditShell->AcceptRedline(0);
+
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ assertXPath(pXmlDoc, "/root/page"_ostr, 1);
+ // This was 1 (bad empty table)
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab"_ostr, 0);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf155345)
+{
+ createSwDoc("tdf144057.fodt");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc());
+ SwRootFrame* pLayout(pDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+
+ // reject all deletions
+ dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
+
+ // enable redlining
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+ pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+
+ // delete table column with track changes
+ dispatchCommand(mxComponent, ".uno:DeleteColumns", {});
+
+ discardDumpedLayout();
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ // show tracked column deletions
+ assertXPath(pXmlDoc, "/root/page"_ostr, 4);
+
+ // hide tracked table column deletions
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pLayout->IsHideRedlines());
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+
+ // This was 4 (unhidden tracked table column deletions)
+ assertXPath(pXmlDoc, "/root/page"_ostr, 2);
+
+ // show tracked table column deletions again
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page"_ostr, 4);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf109137)
+{
+ createSwDoc("tdf109137.docx");
+ // FIXME: it's not possible to use 'reload' here because the validation fails with
+ // Error: attribute "text:start-value" has a bad value
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValue> aDescriptor(comphelper::InitPropertySequence({
+ { "FilterName", uno::Any(OUString("writer8")) },
+ }));
+ xStorable->storeToURL(maTempFile.GetURL(), aDescriptor);
+ mxComponent->dispose();
+ mxComponent = loadFromDesktop(maTempFile.GetURL(), "com.sun.star.text.TextDocument");
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ // This was 0, the blue rectangle moved from the 1st to the 2nd page.
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt/anchored/fly/notxt"_ostr,
+ /*nNumberOfNodes=*/1);
+}
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint72) { createSwDoc("forcepoint72-1.rtf"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint75) { createSwDoc("forcepoint75-1.rtf"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testUXTSOREL) { createSwDoc("LIBREOFFICE-UXTSOREL.rtf"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepointFootnoteFrame)
+{
+ createSwDoc("forcepoint-swfootnoteframe-1.rtf");
+}
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint76) { createSwDoc("forcepoint76-1.rtf"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testN4LA0OHZ) { createSwDoc("LIBREOFFICE-N4LA0OHZ.rtf"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint89) { createSwWebDoc("forcepoint89.html"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint90) { createSwDoc("forcepoint90.rtf"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint91) { createSwWebDoc("forcepoint91.html"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint92) { createSwDoc("forcepoint92.doc"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint93)
+{
+ createSwDoc("forcepoint93-1.rtf");
+ createSwDoc("forcepoint93-2.rtf");
+}
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint94) { createSwWebDoc("forcepoint94.html"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint98) { createSwWebDoc("forcepoint98.html"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint100) { createSwWebDoc("forcepoint100.html"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint102) { createSwDoc("forcepoint102.rtf"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint103) { createSwWebDoc("forcepoint103.html"); }
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf147485Forcepoint)
+{
+ createSwDoc("tdf147485-forcepoint.docx");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf118058)
+{
+ createSwDoc("tdf118058.fodt");
+ SwDoc* pDoc = getSwDoc();
+ // This resulted in a layout loop.
+ pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
+}
+
+//just care it doesn't crash/assert
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint99) { createSwWebDoc("forcepoint99.html"); }
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf128611)
+{
+ createSwDoc("tdf128611.fodt");
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ CPPUNIT_ASSERT(pXmlDoc);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 14
+ // i.e. there were multiple portions in the first paragraph of the A1 cell, which means that the
+ // rotated text was broken into multiple lines without a good reason.
+ assertXPathContent(pXmlDoc, "//tab/row/cell[1]/txt"_ostr, "Abcd efghijkl");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf142694)
+{
+ createSwDoc("tdf142694-1.odt");
+
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ // the problem with this table is that the 3rd text frame (inside a nested
+ // table) contains an as-char fly that doesn't fit on a page with the
+ // repeated header row; currently it's split so that the 3rd text frame is
+ // on a page of its own and extends outside the table.
+
+ assertXPathNoAttribute(pXmlDoc, "/root/page[4]/body/tab[1]"_ostr, "precede"_ostr);
+ CPPUNIT_ASSERT(!getXPath(pXmlDoc, "/root/page[4]/body/tab[1]"_ostr, "follow"_ostr).isEmpty());
+ assertXPath(pXmlDoc, "/root/page[4]/body/tab[1]/row[1]/cell[1]/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[4]/body/tab[1]/row[2]/cell[1]/txt"_ostr, 2);
+ CPPUNIT_ASSERT(!getXPath(pXmlDoc, "/root/page[5]/body/tab[1]"_ostr, "precede"_ostr).isEmpty());
+ assertXPathNoAttribute(pXmlDoc, "/root/page[5]/body/tab[1]"_ostr, "follow"_ostr);
+ assertXPath(pXmlDoc, "/root/page[5]/body/tab[1]/row[1]/cell[1]/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[5]/body/tab[1]/row[2]/cell[1]/tab"_ostr, 1);
+ assertXPathNoAttribute(pXmlDoc, "/root/page[5]/body/tab[1]/row[2]/cell[1]/tab"_ostr,
+ "follow"_ostr);
+ assertXPath(pXmlDoc, "/root/page[5]/body/tab[1]/row[2]/cell[1]/tab/row/cell/txt"_ostr, 1);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf152413)
+{
+ createSwDoc("tdf152413.fodt");
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+ // Without the fix in place, this test would have failed with
+ // - Expected: 1
+ // - Actual : 2
+ // - In <>, XPath '/root/page/body/txt/SwParaPortion/SwLineLayout/SwLinePortion' number of nodes is incorrect
+ assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout/SwLinePortion"_ostr,
+ "portion"_ostr, u"صِرَ ٰطَ"_ustr);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf125893)
+{
+ createSwDoc("tdf125893.docx");
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ // This was 400. The paragraph must have zero top border.
+ assertXPath(pXmlDoc, "/root/page/body/txt[4]/infos/prtBounds"_ostr, "top"_ostr, "0");
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */