Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  uiwriter8.cxx

  Sprache: C
 

/* -*- 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 <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <vcl/filter/PDFiumLibrary.hxx>
#include <vcl/scheduler.hxx>
#include <vcl/TypeSerializer.hxx>
#include <com/sun/star/awt/FontWeight.hpp>
#include <com/sun/star/drawing/GraphicExportFilter.hpp>
#include <IDocumentDrawModelAccess.hxx>
#include <com/sun/star/text/XTextFrame.hpp>
#include <com/sun/star/text/XTextTable.hpp>
#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
#include <com/sun/star/text/XPageCursor.hpp>
#include <com/sun/star/view/XSelectionSupplier.hpp>
#include <comphelper/propertysequence.hxx>
#include <boost/property_tree/json_parser.hpp>
#include <frameformats.hxx>
#include <tools/json_writer.hxx>
#include <unotools/streamwrap.hxx>
#include <editeng/lrspitem.hxx>
#include <sfx2/linkmgr.hxx>

#include <wrtsh.hxx>
#include <UndoManager.hxx>
#include <unotxdoc.hxx>
#include <drawdoc.hxx>
#include <dcontact.hxx>
#include <svx/svdpage.hxx>
#include <ndtxt.hxx>
#include <txtfld.hxx>
#include <IDocumentFieldsAccess.hxx>
#include <IDocumentLinksAdministration.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <rootfrm.hxx>
#include <redline.hxx>
#include <itabenum.hxx>
#include <officecfg/Office/Common.hxx>

namespace
{
/// 8th set of tests asserting the behavior of Writer user interface shells.
class SwUiWriterTest8 : public SwModelTestBase
{
public:
    SwUiWriterTest8()
        : SwModelTestBase(u"/sw/qa/extras/uiwriter/data/"_ustr)
    {
    }
};

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf131684)
{
    createSwDoc("tdf131684.docx");

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());

    //Use selectAll 3 times in a row
    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());

    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());

    // without the fix, it crashes
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());

    // check that the text frame has the correct upper
    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    OUString const sectionId = getXPath(pXmlDoc, "/root/page[1]/body/section[7]""id");
    OUString const sectionLower = getXPath(pXmlDoc, "/root/page[1]/body/section[7]""lower");
    OUString const textId = getXPath(pXmlDoc, "/root/page[1]/body/section[7]/txt[1]""id");
    OUString const textUpper = getXPath(pXmlDoc, "/root/page[1]/body/section[7]/txt[1]""upper");
    CPPUNIT_ASSERT_EQUAL(textId, sectionLower);
    CPPUNIT_ASSERT_EQUAL(sectionId, textUpper);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132420)
{
    createSwDoc("tdf132420.odt");

    CPPUNIT_ASSERT_EQUAL(12, getShapes());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(0, getShapes());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    //Without the fix in place, 1 frame and 1 image would be gone and getShapes would return 10
    CPPUNIT_ASSERT_EQUAL(12, getShapes());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132744)
{
    createSwDoc("tdf132744.odt");
    SwDoc* pDoc = getSwDoc();

    // disable change tracking to cut the table
    pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete
                                                      | RedlineFlags::ShowInsert);

    CPPUNIT_ASSERT_MESSAGE("redlining should be off",
                           !pDoc->getIDocumentRedlineAccess().IsRedlineOn());

    CPPUNIT_ASSERT_EQUAL(1, getShapes());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(0, getShapes());

    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    //Without the fix in place, the image wouldn't be pasted
    CPPUNIT_ASSERT_EQUAL(1, getShapes());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146622)
{
    createSwDoc("TC-table-del-add.docx");
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell);

    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());

    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
                                                    uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTables->getCount());
    uno::Reference<container::XNameAccess> xTableNames = xTablesSupplier->getTextTables();
    CPPUNIT_ASSERT(xTableNames->hasByName(u"Table1"_ustr));
    uno::Reference<text::XTextTable> xTable1(xTableNames->getByName(u"Table1"_ustr),
                                             uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());

    dispatchCommand(mxComponent, u".uno:DeleteRows"_ustr, {});

    // This was 3 (deleting the already deleted row with change tracking)
    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    dispatchCommand(mxComponent, u".uno:DeleteRows"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    dispatchCommand(mxComponent, u".uno:DeleteRows"_ustr, {});
    // This was 2 (deleting the already deleted table with change tracking)
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTables->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());

    // check that the first table was deleted with change tracking
    dispatchCommand(mxComponent, u".uno:AcceptAllTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());

    // Undo AcceptAllTrackedChanges and DeleteRows
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    // now only the second table deleted by AcceptAllTrackedChanges
    dispatchCommand(mxComponent, u".uno:AcceptAllTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146962)
{
    // load a 2-row table, set Hide Changes mode and delete the first row with change tracking
    createSwDoc("tdf116789.fodt");
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell);

    // enable redlining
    dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());
    // hide changes
    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());

    dispatchCommand(mxComponent, u".uno:DeleteRows"_ustr, {});

    // Without the fix in place, the deleted row would be visible

    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    // This was 2
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 1);

    // check it in Show Changes mode

    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(!pWrtShell->GetLayout()->IsHideRedlines());

    pXmlDoc = parseLayoutDump();
    // 2 rows are visible now
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);

    // check it in Hide Changes mode again

    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());

    pXmlDoc = parseLayoutDump();
    // only a single row is visible again
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 1);

    // tdf#148227 check Undo of tracked table row deletion

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    pXmlDoc = parseLayoutDump();
    // This was 1
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf159026)
{
    // load a floating table (tables in DOCX footnotes
    // imported as floating tables in Writer)
    createSwDoc("tdf159026.docx");
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell);

    // enable redlining
    dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());
    // hide changes
    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());

    // select table with SelectionSupplier
    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());

    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
    uno::Reference<view::XSelectionSupplier> xSelSupplier(xModel->getCurrentController(),
                                                          uno::UNO_QUERY_THROW);
    // select floating table (table in a frame)
    xSelSupplier->select(xIndexAccess->getByIndex(0));

    // delete table with track changes
    dispatchCommand(mxComponent, u".uno:DeleteTable"_ustr, {});

    // tracked table deletion
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());

    // hidden table
    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    assertXPath(pXmlDoc, "//tab", 0);

    // delete frame
    uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess2(xTextFramesSupplier->getTextFrames(),
                                                          uno::UNO_QUERY);
    xSelSupplier->select(xIndexAccess2->getByIndex(0));
    dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});

    // undo frame deletion
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    // undo tracked table deletion

    // This resulted crashing
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf147347)
{
    // load a 2-row table, set Hide Changes mode and delete the table with change tracking
    createSwDoc("tdf116789.fodt");
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell);

    // enable redlining
    dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());
    // hide changes
    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());

    dispatchCommand(mxComponent, u".uno:DeleteTable"_ustr, {});

    // Without the fix in place, the deleted row would be visible

    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    // This was 1
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 0);

    // check it in Show Changes mode

    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(!pWrtShell->GetLayout()->IsHideRedlines());

    pXmlDoc = parseLayoutDump();
    // 2 rows are visible now
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);

    // check it in Hide Changes mode again

    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());

    pXmlDoc = parseLayoutDump();
    // no visible row again
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 0);

    // tdf#148228 check Undo of tracked table deletion

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    pXmlDoc = parseLayoutDump();
    // This was 0
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf153819)
{
    // copy a table before a deleted table in Hide Changes mode
    createSwDoc("tdf153819.fodt");
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell);

    // hide changes
    CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());

    dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
    dispatchCommand(mxComponent, u".uno:GoDown"_ustr, {});

    // Without the fix in place, this test would have crashed here
    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    // FIXME: Show Changes, otherwise ~SwTableNode() would have crashed
    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148345)
{
    // load a 2-row table, set Hide Changes mode and delete the first row with change tracking
    createSwDoc("tdf116789.fodt");
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell);

    // enable redlining
    dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());
    // hide changes
    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());

    dispatchCommand(mxComponent, u".uno:DeleteRows"_ustr, {});

    // Without the fix in place, the deleted row would be visible

    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    // This was 2
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 1);

    // check it in Show Changes mode

    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(!pWrtShell->GetLayout()->IsHideRedlines());

    pXmlDoc = parseLayoutDump();
    // 2 rows are visible now
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);

    // check it in Hide Changes mode again

    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());

    pXmlDoc = parseLayoutDump();
    // only a single row is visible again
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 1);

    // tdf#148227 check Reject All of tracked table row deletion

    dispatchCommand(mxComponent, u".uno:RejectAllTrackedChanges"_ustr, {});
    pXmlDoc = parseLayoutDump();
    // This was 1
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf141391)
{
    // table insertion in the first paragraph of the cell
    // overwrites the row content, instead of inserting a nested table

    // load a 2-row table
    createSwDoc("tdf116789.fodt");
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell);

    // select the table, and copy it into at paragraph start of cell "A2"

    dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
    // remove the selection and positionate the cursor at beginning of A2
    pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    // 3-row, overwriting cells of the second row and inserting a new row
    // with the 2-row clipboard table content
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 3);
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout",
                "portion", u"hello");

    // Undo

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    pXmlDoc = parseLayoutDump();
    // 2 rows again, no copied text content
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/SwParaPortion", 0);

    // insert the 2-row table into the second paragraph of cell "A2" as a nested table
    // For this it's enough to positionate the text cursor not in the first paragraph

    // insert some text and an empty paragraph
    pWrtShell->Insert(u"Some text..."_ustr);
    pWrtShell->SplitNode();
    Scheduler::ProcessEventsToIdle();
    pXmlDoc = parseLayoutDump();
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt", 2);
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/SwParaPortion/SwLineLayout",
                "portion", u"Some text...");
    // the empty paragraph in A2
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[2]/SwParaPortion", 0);

    // insert the table, as a nested one in cell "A2"
    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
    pXmlDoc = parseLayoutDump();
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab", 1);
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab/row", 2);

    // Undo

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    pXmlDoc = parseLayoutDump();
    // 2 rows again, no copied text content
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/SwParaPortion/SwLineLayout",
                "portion", u"Some text...");

    // copy the 2-row table into the first paragraph of cell "A2",
    // but not at paragraph start (changed behaviour)

    pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
    pWrtShell->Insert(u"and some text again in the first paragraph to be sure..."_ustr);
    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    pXmlDoc = parseLayoutDump();

    // 3-row, overwriting cells of the second row and inserting a new row
    // with the 2-row clipboard table content

    // This was 2 (nested table)
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 3);
    // This was "Some text..." with a nested table
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout",
                "portion", u"hello");
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148791)
{
    // test Paste as Rows Above with centered table alignment

    // load a 2-row table
    createSwDoc("tdf116789.fodt");
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell);

    // select and copy the table, and Paste As Rows Above

    dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
    // remove the selection and positionate the cursor at beginning of A2
    pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
    pWrtShell->Up(/*bSelect=*/false);
    dispatchCommand(mxComponent, u".uno:PasteRowsBefore"_ustr, {});

    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    // Paste as Rows Above results 4-row table with default table alignment
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 4);
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[1]/cell[1]/txt/SwParaPortion/SwLineLayout",
                "portion", u"hello");
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[3]/cell[1]/txt/SwParaPortion/SwLineLayout",
                "portion", u"hello");

    // set table alignment to center, select and copy the table again
    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());

    uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);

    // Default table alignment
    CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::FULL,
                         getProperty<sal_Int16>(xTextTable, u"HoriOrient"_ustr));

    //CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xTextTable, "TableTemplateName"));
    uno::Reference<beans::XPropertySet> xTableProps(xTextTable, uno::UNO_QUERY_THROW);

    xTableProps->setPropertyValue(u"HoriOrient"_ustr, uno::Any(text::HoriOrientation::CENTER));

    CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER,
                         getProperty<sal_Int16>(xTextTable, u"HoriOrient"_ustr));

    dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
    // remove the selection and positionate the cursor at beginning of A2
    pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
    pWrtShell->Up(/*bSelect=*/false);
    pWrtShell->Up(/*bSelect=*/false);
    pWrtShell->Up(/*bSelect=*/false);
    dispatchCommand(mxComponent, u".uno:PasteRowsBefore"_ustr, {});

    pXmlDoc = parseLayoutDump();
    // This was 5 (inserting only a single row for the 4-row clipboard content, and
    // overwriting 3 existing rows)
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 8);
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[1]/cell[1]/txt/SwParaPortion/SwLineLayout",
                "portion", u"hello");
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[3]/cell[1]/txt/SwParaPortion/SwLineLayout",
                "portion", u"hello");
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[5]/cell[1]/txt/SwParaPortion/SwLineLayout",
                "portion", u"hello");
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[7]/cell[1]/txt/SwParaPortion/SwLineLayout",
                "portion", u"hello");

    // tdf#64902 add a test case for nested tables

    // insert a nested table, and copy as paste as rows above the whole table with it
    dispatchCommand(mxComponent, u".uno:PasteNestedTable"_ustr, {});
    dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
    // remove the selection and positionate the cursor at beginning of A2
    pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
    // skip 7 table rows plus 4 rows of the nested table
    for (int i = 0; i < 7 + 4; ++i)
        pWrtShell->Up(/*bSelect=*/false);
    dispatchCommand(mxComponent, u".uno:PasteRowsBefore"_ustr, {});

    pXmlDoc = parseLayoutDump();
    // rows of the nested table doesn't effect row number of the main table
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 16);
    // there are two nested tables after the paste
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab", 2);

    // tdf#64902 add a test case for repeated table headings

    xTableProps->setPropertyValue(u"RepeatHeadline"_ustr, uno::Any(true));
    CPPUNIT_ASSERT(getProperty<bool>(xTextTable, u"RepeatHeadline"_ustr));

    xTableProps->setPropertyValue(u"HeaderRowCount"_ustr, uno::Any(sal_Int32(3)));
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), getProperty<sal_Int32>(xTextTable, u"HeaderRowCount"_ustr));

    dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
    // remove the selection and positionate the cursor at beginning of A2
    pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
    // skip 15 table rows plus 4 * 2 rows of the nested tables
    for (int i = 0; i < 15 + 4 * 2; ++i)
        pWrtShell->Up(/*bSelect=*/false);
    dispatchCommand(mxComponent, u".uno:PasteRowsBefore"_ustr, {});

    pXmlDoc = parseLayoutDump();
    // repeating table header (and its thead/tbody indentation) doesn't effect row number
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 32);
    // there are two nested tables after the paste
    assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab", 4);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf135014)
{
    createSwDoc();

    uno::Sequence<beans::PropertyValue> aArgs(
        comphelper::InitPropertySequence({ { "KeyModifier", uno::Any(sal_Int32(0)) } }));

    // Toggle Numbering List
    dispatchCommand(mxComponent, u".uno:DefaultBullet"_ustr, aArgs);

    uno::Sequence<beans::PropertyValue> aArgs2(comphelper::InitPropertySequence(
        { { "Param", uno::Any(u"NewNumberingStyle"_ustr) },
          { "Family", uno::Any(static_cast<sal_Int16>(SfxStyleFamily::Pseudo)) } }));

    // New Style from selection
    dispatchCommand(mxComponent, u".uno:StyleNewByExample"_ustr, aArgs2);

    // Without the fix in place, this test would have failed here
    saveAndReload(u"Office Open XML Text"_ustr);

    xmlDocUniquePtr pXmlStyles = parseExport(u"word/styles.xml"_ustr);
    assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='NewNumberingStyle']/w:qFormat", 1);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf130629)
{
    createSwDoc();

    uno::Sequence<beans::PropertyValue> aArgs(
        comphelper::InitPropertySequence({ { "KeyModifier", uno::Any(KEY_MOD1) } }));

    dispatchCommand(mxComponent, u".uno:BasicShapes.diamond"_ustr, aArgs);

    CPPUNIT_ASSERT_EQUAL(1, getShapes());

    // Undo twice
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(0, getShapes());

    // Shape toolbar is active, use ESC before inserting a new shape
    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_ESCAPE);
    Scheduler::ProcessEventsToIdle();

    // Without the fix in place, this test would have crashed here
    dispatchCommand(mxComponent, u".uno:BasicShapes.diamond"_ustr, aArgs);

    CPPUNIT_ASSERT_EQUAL(1, getShapes());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf145584)
{
    std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
    if (!pPDFium)
    {
        return;
    }
    createSwDoc();
    SwWrtShell* const pWrtSh = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtSh);

    pWrtSh->Insert(u"Hello World"_ustr);

    // Select 'World'
    pWrtSh->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 5, /*bBasicCall=*/false);

    // Save as PDF.
    uno::Sequence<beans::PropertyValue> aFilterData(
        comphelper::InitPropertySequence({ { "Selection", uno::Any(true) } }));

    uno::Sequence<beans::PropertyValue> aDescriptor(
        comphelper::InitPropertySequence({ { "FilterName", uno::Any(u"writer_pdf_Export"_ustr) },
                                           { "FilterData", uno::Any(aFilterData) },
                                           { "URL", uno::Any(maTempFile.GetURL()) } }));

    // Without the fix in place, this test would have crashed here
    dispatchCommand(mxComponent, u".uno:ExportToPDF"_ustr, aDescriptor);

    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parsePDFExport();
    CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());
    std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/0);
    CPPUNIT_ASSERT(pPdfPage);
    CPPUNIT_ASSERT_EQUAL(1, pPdfPage->getObjectCount());
    std::unique_ptr<vcl::pdf::PDFiumTextPage> pPdfTextPage = pPdfPage->getTextPage();
    CPPUNIT_ASSERT(pPdfTextPage);

    std::unique_ptr<vcl::pdf::PDFiumPageObject> pPageObject = pPdfPage->getObject(0);
    OUString sText = pPageObject->getText(pPdfTextPage);
    CPPUNIT_ASSERT_EQUAL(u"World"_ustr, sText);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf131728)
{
    std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
    if (!pPDFium)
    {
        return;
    }
    createSwDoc("tdf131728.docx");
    SwDoc* const pDoc = getSwDoc();
    SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtSh);

    // Save as PDF.
    uno::Sequence<beans::PropertyValue> aFilterData(comphelper::InitPropertySequence(
        { { "ExportBookmarksToPDFDestination", uno::Any(true) } }));

    uno::Sequence<beans::PropertyValue> aDescriptor(
        comphelper::InitPropertySequence({ { "FilterName", uno::Any(u"writer_pdf_Export"_ustr) },
                                           { "FilterData", uno::Any(aFilterData) },
                                           { "URL", uno::Any(maTempFile.GetURL()) } }));

    dispatchCommand(mxComponent, u".uno:ExportToPDF"_ustr, aDescriptor);

    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parsePDFExport();
    CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());

    std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/0);
    CPPUNIT_ASSERT(pPdfPage);

    // Without the fix in place, this test would have bad order
    // (starting with the outlines of text frames)
    CPPUNIT_ASSERT_EQUAL(u"Article 1. Definitions\n"
                         " Apple\n"
                         " Bread\n"
                         " Cable\n"
                         " Cable\n" // ???
                         "Article 2. Three style separators in one line!\n"
                         " Heading 2\n"
                         " Heading 2 Again\n"_ustr,
                         pPdfDocument->getBookmarks());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf95239)
{
    std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
    if (!pPDFium)
    {
        return;
    }
    createSwDoc("tdf95239.fodt");
    SwDoc* const pDoc = getSwDoc();
    SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtSh);

    // Save as PDF.
    uno::Sequence<beans::PropertyValue> aFilterData(comphelper::InitPropertySequence(
        { { "ExportBookmarksToPDFDestination", uno::Any(true) } }));

    uno::Sequence<beans::PropertyValue> aDescriptor(
        comphelper::InitPropertySequence({ { "FilterName", uno::Any(u"writer_pdf_Export"_ustr) },
                                           { "FilterData", uno::Any(aFilterData) },
                                           { "URL", uno::Any(maTempFile.GetURL()) } }));

    dispatchCommand(mxComponent, u".uno:ExportToPDF"_ustr, aDescriptor);

    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parsePDFExport();
    CPPUNIT_ASSERT_EQUAL(2, pPdfDocument->getPageCount());

    std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/0);
    CPPUNIT_ASSERT(pPdfPage);

    // Without the fix in place, this test would have bad order
    // (starting with the outlines of text frames)
    CPPUNIT_ASSERT_EQUAL(u"H1\n"
                         " H2\n"
                         "  H3\n"
                         "   Lorem\n"
                         "    Vestibulum\n"
                         "    Integer\n"
                         "   Aliquam\n"
                         "    Donec\n"
                         "    Praesent\n"
                         "  H3\n"
                         "   Lorem\n"
                         "    Vestibulum\n"
                         "    Integer\n"
                         "   Aliquam\n"
                         "    Donec\n"
                         "    Praesent\n"
                         "H1\n"
                         " H2\n"
                         "  H3\n"
                         "   Lorem\n"
                         "    Vestibulum\n"
                         "    Integer\n"
                         "   Aliquam\n"
                         "    Donec\n"
                         "    Praesent\n"_ustr,
                         pPdfDocument->getBookmarks());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf152575)
{
    // FIXME: the DPI check should be removed when either (1) the test is fixed to work with
    // non-default DPI; or (2) unit tests on Windows are made to use svp VCL plugin.
    if (!IsDefaultDPI())
        return;
    std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
    if (!pPDFium)
        return;

    createSwDoc("152575.fodt");

    // Save as PDF.
    uno::Sequence<beans::PropertyValue> aFilterData(
        comphelper::InitPropertySequence({ { "ExportNotesInMargin", uno::Any(true) } }));

    uno::Sequence<beans::PropertyValue> aDescriptor(
        comphelper::InitPropertySequence({ { "FilterName", uno::Any(u"writer_pdf_Export"_ustr) },
                                           { "FilterData", uno::Any(aFilterData) },
                                           { "URL", uno::Any(maTempFile.GetURL()) } }));

    // Without the fix in place, this test would have crashed here
    dispatchCommand(mxComponent, u".uno:ExportToPDF"_ustr, aDescriptor);

    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parsePDFExport();
    CPPUNIT_ASSERT_EQUAL(3, pPdfDocument->getPageCount());
    std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/1);
    CPPUNIT_ASSERT(pPdfPage);
    // Without the fix for tdf#152575 this would be only 42 objects
    CPPUNIT_ASSERT_EQUAL(50, pPdfPage->getObjectCount());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf140731)
{
    createSwDoc();
    SwDoc* const pDoc = getSwDoc();
    SwWrtShell* const pWrtSh = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtSh);

    pWrtSh->Insert(u"Lorem"_ustr);

    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F3);
    Scheduler::ProcessEventsToIdle();

    // generating a big text with ~60k words and several paragraphs
    for (sal_Int32 i = 0; i < 8; ++i)
    {
        dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

        dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});

        dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

        dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
    }

    dispatchCommand(mxComponent, u".uno:GoToStartOfDoc"_ustr, {});

    // Format->Text operations on small selections (which would generate <~500 redlines)
    // changetracking still working
    dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});

    SwCursorShell* pShell(pDoc->GetEditShell());
    CPPUNIT_ASSERT(pShell);

    pShell->SelectTextModel(1, 500);

    dispatchCommand(mxComponent, u".uno:ChangeCaseToTitleCase"_ustr, {});

    SwEditShell* const pEditShell(pDoc->GetEditShell());
    CPPUNIT_ASSERT(pEditShell);
    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(120),
                         pEditShell->GetRedlineCount());

    //Removing all the redlines.
    dispatchCommand(mxComponent, u".uno:RejectAllTrackedChanges"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(0), pEditShell->GetRedlineCount());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    dispatchCommand(mxComponent, u".uno:ChangeCaseToTitleCase"_ustr, {});

    // Without the fix in place, on big selections writer would freeze. Now it ignores change tracking.
    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(0), pEditShell->GetRedlineCount());

    // The patch has no effects on the Format->Text operations
    CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Lorem Ipsum Dolor Sit Amet"));

    dispatchCommand(mxComponent, u".uno:ChangeCaseToUpper"_ustr, {});

    CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("LOREM IPSUM DOLOR SIT AMET"));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf116315)
{
    createSwDoc();
    SwWrtShell* const pWrtSh = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtSh);

    pWrtSh->Insert(u"This is a test"_ustr);
    pWrtSh->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 4, /*bBasicCall=*/false);

    SwXTextDocument* pTextDoc = getSwTextDoc();
    for (sal_Int32 i = 0; i < 5; ++i)
    {
        pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
        Scheduler::ProcessEventsToIdle();

        // Title Case
        CPPUNIT_ASSERT_EQUAL(u"This is a Test"_ustr, getParagraph(1)->getString());

        pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
        Scheduler::ProcessEventsToIdle();

        // Upper Case
        CPPUNIT_ASSERT_EQUAL(u"This is a TEST"_ustr, getParagraph(1)->getString());

        pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
        Scheduler::ProcessEventsToIdle();

        // Lower Case
        CPPUNIT_ASSERT_EQUAL(u"This is a test"_ustr, getParagraph(1)->getString());
    }
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testInsertAutoTextIntoListFromParaStyle)
{
    createSwDoc("stylewithlistandindents.fodt");
    SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell);

    pWrtShell->FwdPara();
    pWrtShell->EndPara(/*bSelect=*/false);
    // expands autotext (via F3)
    pWrtShell->Insert(u" jacr"_ustr);

    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F3);
    Scheduler::ProcessEventsToIdle();

    pWrtShell->SttEndDoc(/*bStt=*/true);
    pWrtShell->FwdPara();

    SwNumRule* pNumRule;
    SvxTextLeftMarginItem const* pTextLeftMargin;
    SvxFirstLineIndentItem const* pFirstLineIndent;

    {
        SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() };
        // numrule from paragraph style, but not from direct formatting
        auto pSet{ rNode.GetpSwAttrSet() };
        CPPUNIT_ASSERT(pSet);
        // list id was set
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false));
        // the numrule is set on the paragraph style, not on the paragraph
        CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_PARATR_NUMRULE, false));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, true));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT,
                             pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, true));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_MARGIN_TEXTLEFTfalse));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true));
        CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName().toString());
        CPPUNIT_ASSERT_EQUAL(u"Item We confirm receipt of your application material."_ustr,
                             rNode.GetText());
        pNumRule = rNode.GetNumRule();
        pTextLeftMargin = &rNode.GetAttr(RES_MARGIN_TEXTLEFT);
        pFirstLineIndent = &rNode.GetAttr(RES_MARGIN_FIRSTLINE);
    }

    pWrtShell->FwdPara();

    {
        SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() };
        auto pSet{ rNode.GetpSwAttrSet() };
        CPPUNIT_ASSERT(pSet);
        // list id was set
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false));
        // middle paragraph was pasted - has numrule and indents applied directly
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, false));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false));
        CPPUNIT_ASSERT_EQUAL(u"Default Paragraph Style"_ustr,
                             rNode.GetTextColl()->GetName().toString());
        CPPUNIT_ASSERT(rNode.GetText().startsWith("As more applicants applied"));
        CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule());
        CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->ResolveTextLeft({}),
                             rNode.GetAttr(RES_MARGIN_TEXTLEFT).ResolveTextLeft({}));
        CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->ResolveTextFirstLineOffset({}),
                             rNode.GetAttr(RES_MARGIN_FIRSTLINE).ResolveTextFirstLineOffset({}));
    }

    pWrtShell->FwdPara();

    {
        SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() };
        // numrule from paragraph style, but not from direct formatting
        auto pSet{ rNode.GetpSwAttrSet() };
        CPPUNIT_ASSERT(pSet);
        // list id was set
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false));
        // the numrule is set on the paragraph style, not on the paragraph
        CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_PARATR_NUMRULE, false));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, true));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT,
                             pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, true));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_MARGIN_TEXTLEFTfalse));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true));
        CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName().toString());
        CPPUNIT_ASSERT(rNode.GetText().endsWith("as soon as we have come to a decision."));
        CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule());
        CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->ResolveTextLeft({}),
                             rNode.GetAttr(RES_MARGIN_TEXTLEFT).ResolveTextLeft({}));
        CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->ResolveTextFirstLineOffset({}),
                             rNode.GetAttr(RES_MARGIN_FIRSTLINE).ResolveTextFirstLineOffset({}));
    }

    pWrtShell->FwdPara();

    {
        SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() };
        // numrule from paragraph style, but not from direct formatting
        auto pSet{ rNode.GetpSwAttrSet() };
        CPPUNIT_ASSERT(pSet);
        // list id was set
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false));
        // the numrule is set on the paragraph style, not on the paragraph
        CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_PARATR_NUMRULE, false));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, true));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT,
                             pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, true));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_MARGIN_TEXTLEFTfalse));
        CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true));
        CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName().toString());
        CPPUNIT_ASSERT_EQUAL(u"more"_ustr, rNode.GetText()); // pre-existing list item
        CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule());
        CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->ResolveTextLeft({}),
                             rNode.GetAttr(RES_MARGIN_TEXTLEFT).ResolveTextLeft({}));
        CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->ResolveTextFirstLineOffset({}),
                             rNode.GetAttr(RES_MARGIN_FIRSTLINE).ResolveTextFirstLineOffset({}));
    }
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf144364)
{
    createSwDoc();
    SwWrtShell* const pWrtSh = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtSh);

    // expands autotext (via F3)
    pWrtSh->Insert(u"AR"_ustr);

    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F3);
    Scheduler::ProcessEventsToIdle();

    // was ...'letter of <placeholder:"November 21, 2004":"Click placeholder and overwrite">'
    CPPUNIT_ASSERT_EQUAL(
        u"We hereby acknowledge the receipt of your letter of <November 21, 2004>."_ustr,
        getParagraph(1)->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146248)
{
    createSwDoc("tdf146248.docx");

    uno::Reference<beans::XPropertySet> xPageStyle(
        getStyles(u"PageStyles"_ustr)->getByName(u"Standard"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));

    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    // Delete the header
    pWrtShell->ChangeHeaderOrFooter(UIName(u"Default Page Style"_ustr), truefalsefalse);

    CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));

    // Without the fix in place, this test would have crashed here
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf161741)
{
    // Redo of header change causes LO to crash
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    sw::UndoManager& rUndoManager = pDoc->GetUndoManager();

    uno::Reference<beans::XPropertySet> xPageStyle(
        getStyles(u"PageStyles"_ustr)->getByName(u"Standard"_ustr), uno::UNO_QUERY);

    // sanity checks: verify baseline status
    CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rUndoManager.GetUndoActionCount());

    // Create a header
    pWrtShell->ChangeHeaderOrFooter(UIName(u"Default Page Style"_ustr), /*header*/ true,
                                    /*on*/ true, false);
    CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));

    // create an additional non-header undo point
    pWrtShell->Insert(u"crash_test"_ustr); // three undo points
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rUndoManager.GetUndoActionCount());

    // undo all the changes in one pass
    uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({
        { "Undo", uno::Any(sal_Int32(4)) },
    }));
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, aPropertyValues); // undo all 4 actions
    CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rUndoManager.GetUndoActionCount());

    // Crash avoided by clearing the entire redo stack. This redo request will do nothing.
    // Without the fix in place, this test would have crashed here
    dispatchCommand(mxComponent, u".uno:Redo"_ustr, {}); // redo first (Header) change
    // Since Redo is "cleared", the redo did nothing, thus the Header remains off
    CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf152964)
{
    createSwDoc();

    dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});

    uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
        { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));

    dispatchCommand(mxComponent, u".uno:InsertTable"_ustr, aArgs);

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());

    SwDoc* pDoc = getSwDoc();
    SwEditShell* const pEditShell(pDoc->GetEditShell());
    CPPUNIT_ASSERT(pEditShell);
    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), pEditShell->GetRedlineCount());
    dispatchCommand(mxComponent, u".uno:GoDown"_ustr, {});
    dispatchCommand(mxComponent, u".uno:DeleteRows"_ustr, {});
    dispatchCommand(mxComponent, u".uno:DeleteRows"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount());

    // Without the fix in place, this test would have crashed here
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), pEditShell->GetRedlineCount());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(0), pEditShell->GetRedlineCount());

    dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), pEditShell->GetRedlineCount());
    dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf107427)
{
    createSwDoc();

    dispatchCommand(
        mxComponent,
        u".uno:InsertPageHeader?PageStyle:string=Default%20Page%20Style&On:bool=true"_ustr, {});
    uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
        { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));

    dispatchCommand(mxComponent, u".uno:InsertTable"_ustr, aArgs);

    xmlDocUniquePtr pLayout = parseLayoutDump();
    assertXPath(pLayout, "/root/page[1]/header/tab/row", 2);

    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    // Delete the header
    pWrtShell->ChangeHeaderOrFooter(UIName(u"Default Page Style"_ustr), truefalsefalse);

    pLayout = parseLayoutDump();
    assertXPath(pLayout, "/root/page[1]/header", 0);

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    pLayout = parseLayoutDump();
    assertXPath(pLayout, "/root/page[1]/header/tab/row", 2);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf141613)
{
    createSwDoc();
    SwWrtShell* const pWrtSh = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtSh);

    pWrtSh->Insert(u"Test"_ustr);

    dispatchCommand(
        mxComponent,
        u".uno:InsertPageHeader?PageStyle:string=Default%20Page%20Style&On:bool=true"_ustr, {});

    uno::Reference<beans::XPropertySet> xPageStyle(
        getStyles(u"PageStyles"_ustr)->getByName(u"Standard"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));
    CPPUNIT_ASSERT_EQUAL(u"Test"_ustr, getParagraph(1)->getString());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));
    CPPUNIT_ASSERT_EQUAL(u"Test"_ustr, getParagraph(1)->getString());

    // Without the fix in place, this test would have crashed here
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(u""_ustr, getParagraph(1)->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf107494)
{
    createSwDoc();

    // Create a graphic object, but don't insert it yet.
    uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
    uno::Reference<beans::XPropertySet> xTextGraphic(
        xFactory->createInstance(u"com.sun.star.text.TextGraphicObject"_ustr), uno::UNO_QUERY);

    uno::Reference<text::XTextContent> xTextContent(xTextGraphic, uno::UNO_QUERY);

    uno::Reference<beans::XPropertySet> xPageStyle(
        getStyles(u"PageStyles"_ustr)->getByName(u"Standard"_ustr), uno::UNO_QUERY);

    xPageStyle->setPropertyValue(u"HeaderIsOn"_ustr, uno::Any(true));

    uno::Reference<text::XText> xHeader(
        getProperty<uno::Reference<text::XText>>(xPageStyle, u"HeaderText"_ustr));
    CPPUNIT_ASSERT(xHeader.is());
    uno::Reference<text::XTextCursor> xHeaderCursor(xHeader->createTextCursor());

    xHeader->insertTextContent(xHeaderCursor, xTextContent, false);

    CPPUNIT_ASSERT_EQUAL(1, getShapes());

    xPageStyle->setPropertyValue(u"HeaderIsOn"_ustr, uno::Any(false));

    CPPUNIT_ASSERT_EQUAL(0, getShapes());

    xPageStyle->setPropertyValue(u"FooterIsOn"_ustr, uno::Any(true));

    uno::Reference<text::XText> xFooter(
        getProperty<uno::Reference<text::XText>>(xPageStyle, u"FooterText"_ustr));
    CPPUNIT_ASSERT(xFooter.is());
    uno::Reference<text::XTextCursor> xFooterCursor(xFooter->createTextCursor());

    xTextGraphic.set(xFactory->createInstance(u"com.sun.star.text.TextGraphicObject"_ustr),
                     uno::UNO_QUERY);

    xTextContent.set(xTextGraphic, uno::UNO_QUERY);

    xFooter->insertTextContent(xFooterCursor, xTextContent, false);

    CPPUNIT_ASSERT_EQUAL(1, getShapes());

    xPageStyle->setPropertyValue(u"FooterIsOn"_ustr, uno::Any(false));

    CPPUNIT_ASSERT_EQUAL(0, getShapes());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf133358)
{
    createSwDoc();
    SwWrtShell* const pWrtSh = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtSh);

    pWrtSh->Insert(u"Test"_ustr);

    CPPUNIT_ASSERT_EQUAL(u"Test"_ustr, getParagraph(1)->getString());

    uno::Reference<beans::XPropertyState> xParagraph(getParagraph(1), uno::UNO_QUERY);

    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xParagraph, u"ParaLeftMargin"_ustr));

    dispatchCommand(mxComponent, u".uno:IncrementIndent"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1251),
                         getProperty<sal_Int32>(xParagraph, u"ParaLeftMargin"_ustr));

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xParagraph, u"ParaLeftMargin"_ustr));

    // Without the fix in place, this test would have crashed here
    dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1251),
                         getProperty<sal_Int32>(xParagraph, u"ParaLeftMargin"_ustr));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf131771)
{
    createSwDoc();

    uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
        { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));

    dispatchCommand(mxComponent, u".uno:InsertTable"_ustr, aArgs);

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());

    uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);

    CPPUNIT_ASSERT_EQUAL(u""_ustr, getProperty<OUString>(xTextTable, u"TableTemplateName"_ustr));
    uno::Reference<beans::XPropertySet> xTableProps(xTextTable, uno::UNO_QUERY_THROW);
    xTableProps->setPropertyValue(u"TableTemplateName"_ustr, uno::Any(u"Default Style"_ustr));

    CPPUNIT_ASSERT_EQUAL(u"Default Style"_ustr,
                         getProperty<OUString>(xTextTable, u"TableTemplateName"_ustr));

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
    dispatchCommand(mxComponent, u".uno:GoDown"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount());

    CPPUNIT_ASSERT_EQUAL(u"Default Style"_ustr,
                         getProperty<OUString>(xTextTable, u"TableTemplateName"_ustr));

    uno::Reference<text::XTextTable> xTextTable2(xIndexAccess->getByIndex(1), uno::UNO_QUERY);

    // Without the fix in place, this test would have failed with
    // - Expected: Default Style
    // - Actual  :
    CPPUNIT_ASSERT_EQUAL(u"Default Style"_ustr,
                         getProperty<OUString>(xTextTable2, u"TableTemplateName"_ustr));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf156546)
{
    createSwDoc();

    uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
        { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));

    dispatchCommand(mxComponent, u".uno:InsertTable"_ustr, aArgs);

    uno::Reference<text::XTextTablesSupplier> xTableSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xTables(xTableSupplier->getTextTables(),
                                                    uno::UNO_QUERY);

    // check that table was created and inserted into the document
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});

    // create another document
    createSwDoc();
    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    uno::Reference<text::XTextTablesSupplier> xTableSupplier2(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xTables2(xTableSupplier2->getTextTables(),
                                                     uno::UNO_QUERY);

    // check table exists after paste/undo
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables2->getCount());
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables2->getCount());

    // without the test, writer freezes on redo table paste into new doc
    dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables2->getCount());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf80663)
{
    createSwDoc();

    uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
        { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));

    dispatchCommand(mxComponent, u".uno:InsertTable"_ustr, aArgs);

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());

    dispatchCommand(mxComponent, u".uno:DeleteRows"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf130805)
{
    createSwDoc("tdf130805.odt");
    SwDoc* pDoc = getSwDoc();

    const auto& rFrmFormats = *pDoc->GetSpzFrameFormats();
    CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1)));
    auto pShape = rFrmFormats.front();
    CPPUNIT_ASSERT(pShape);

    SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
    auto pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
    CPPUNIT_ASSERT(pTxBxFrm);

    const SwNode* pTxAnch = pTxBxFrm->GetAnchor().GetAnchorNode();
    const SwNode* pShpAnch = pShape->GetAnchor().GetAnchorNode();
    CPPUNIT_ASSERT(pTxAnch);
    CPPUNIT_ASSERT(pShpAnch);

    CPPUNIT_ASSERT_EQUAL_MESSAGE("The textbox got apart!", pTxAnch->GetIndex(),
                                 pShpAnch->GetIndex());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf107893)
{
    //Open the sample doc
    createSwDoc("tdf107893.odt");
    SwDoc* pDoc = getSwDoc();

    //Get the format of the shape
    const auto& rFrmFormats = *pDoc->GetSpzFrameFormats();
    CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1)));
    auto pShape = rFrmFormats.front();
    CPPUNIT_ASSERT(pShape);

    //Add a textbox
    SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
    SwFrameFormat* pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
    CPPUNIT_ASSERT(pTxBxFrm);

    //Remove the textbox using Undo
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    //Add again
    SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
    pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));

    //This was nullptr because of unsuccessful re-adding
    CPPUNIT_ASSERT_MESSAGE("Textbox cannot be readd after Undo!", pTxBxFrm);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf121031)
{
    createSwDoc();

    uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
        { { "Rows", uno::Any(sal_Int32(3)) }, { "Columns", uno::Any(sal_Int32(3)) } }));

    dispatchCommand(mxComponent, u".uno:InsertTable"_ustr, aArgs);

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());

    dispatchCommand(mxComponent, u".uno:DeleteTable"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());

    // Without the fix in place, the table would be hidden
    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    assertXPath(pXmlDoc, "/root/page[1]/body/tab", 1);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, TestTextBoxCrashAfterLineDel)
{
    // Open the desired file
    createSwDoc("txbx_crash.odt");
    SwDoc* pDoc = getSwDoc();

    // Get the format of the shape
    const auto& rFrmFormats = *pDoc->GetSpzFrameFormats();
    CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1)));
    auto pShape = rFrmFormats.front();
    CPPUNIT_ASSERT(pShape);

    // Add a textbox
    SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
    SwFrameFormat* pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
    CPPUNIT_ASSERT(pTxBxFrm);

    // remove the last paragraph
    auto xCursor = getParagraph(1)->getText()->createTextCursor();
    xCursor->gotoEnd(false);
    xCursor->goLeft(3, true);

    // This caused crash before, now it should pass with the patch.
    xCursor->setString(OUString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146356)
{
    createSwDoc("tdf146356.odt");

    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_MOD2 | awt::Key::RETURN);
    Scheduler::ProcessEventsToIdle();

    emulateTyping(u"Some Text");

    // Without the fix in place, this test would have failed with
    // - Expected: Some Text
    // - Actual  : Table of Contents
    CPPUNIT_ASSERT_EQUAL(u"Some Text"_ustr, getParagraph(1)->getString());

    // tdf#160095: Without the fix in place, this test would have crashed here
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_MOD2 | awt::Key::RETURN);
    Scheduler::ProcessEventsToIdle();

    CPPUNIT_ASSERT_EQUAL(u"Some Text"_ustr, getParagraph(1)->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf121546)
{
    createSwDoc("tdf121546.odt");

    CPPUNIT_ASSERT_EQUAL(u"xxxxxxxxxxxxxxxxxxxx"_ustr, getParagraph(2)->getString());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(1, getParagraphs());

    // Create a new document
    createSwDoc();

    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(u"xxxxxxxxxxxxxxxxxxxx"_ustr, getParagraph(2)->getString());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(1, getParagraphs());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(u"xxxxxxxxxxxxxxxxxxxx"_ustr, getParagraph(2)->getString());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    // Without the fix in place, this test would have crashed here
    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RETURN);
    Scheduler::ProcessEventsToIdle();

    CPPUNIT_ASSERT_EQUAL(2, getParagraphs());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf145621)
{
    createSwDoc("tdf145621.odt");

    CPPUNIT_ASSERT_EQUAL(u"AAAAAA"_ustr, getParagraph(1)->getString());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(u""_ustr, getParagraph(1)->getString());

    // Without the fix in place, this test would have crashed
    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(u"AAAAAA"_ustr, getParagraph(1)->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf134626)
{
    createSwDoc("tdf134626.odt");
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    CPPUNIT_ASSERT_EQUAL(u"Apple"_ustr, getParagraph(1)->getString());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});

    // Create a new document
    createSwDoc();
    pWrtShell = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell);

    // Without the fix in place, this test would have crashed here
    for (sal_Int32 i = 0; i < 5; ++i)
    {
        dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

        CPPUNIT_ASSERT_EQUAL(u"Apple"_ustr, getParagraph(1)->getString());

        dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

        CPPUNIT_ASSERT_EQUAL(u"AppleApple"_ustr, getParagraph(1)->getString());

        dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

        CPPUNIT_ASSERT_EQUAL(u"Apple"_ustr, getParagraph(1)->getString());

        dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

        CPPUNIT_ASSERT_EQUAL(u""_ustr, getParagraph(1)->getString());
    }
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf139566)
{
    createSwDoc();
    SwWrtShell* pWrtSh = getSwDocShell()->GetWrtShell();

    uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
        { { "Rows", uno::Any(sal_Int32(1)) }, { "Columns", uno::Any(sal_Int32(1)) } }));

    dispatchCommand(mxComponent, u".uno:InsertTable"_ustr, aArgs);

    // Move the cursor outside the table
    pWrtSh->Down(/*bSelect=*/false);

    pWrtSh->Insert(u"Test"_ustr);

    CPPUNIT_ASSERT_EQUAL(u"Test"_ustr, getParagraph(2)->getString());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    uno::Reference<frame::XFrames> xFrames = mxDesktop->getFrames();
    sal_Int32 nFrames = xFrames->getCount();

    // Create a second window so the first window looses focus
    dispatchCommand(mxComponent, u".uno:NewWindow"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(nFrames + 1, xFrames->getCount());

    dispatchCommand(mxComponent, u".uno:CloseWin"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(nFrames, xFrames->getCount());

    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xSelections(xModel->getCurrentSelection(),
                                                        uno::UNO_QUERY);

    // Without the fix in place, this test would have failed here
    CPPUNIT_ASSERT(xSelections.is());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf96067)
{
    createSwDoc();

    uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
        { { "Rows", uno::Any(sal_Int32(3)) }, { "Columns", uno::Any(sal_Int32(3)) } }));

    dispatchCommand(mxComponent, u".uno:InsertTable"_ustr, aArgs);

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());

    dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
    dispatchCommand(mxComponent, u".uno:InsertRowsBefore"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf87199)
{
    createSwDoc();

    uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
        { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(1)) } }));

    dispatchCommand(mxComponent, u".uno:InsertTable"_ustr, aArgs);

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());

    uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY);
    xCellA1->setString(u"test1"_ustr);

    uno::Reference<text::XTextRange> xCellA2(xTextTable->getCellByName(u"A2"_ustr), uno::UNO_QUERY);
    xCellA2->setString(u"test2"_ustr);

    dispatchCommand(mxComponent, u".uno:EntireColumn"_ustr, {});
    dispatchCommand(mxComponent, u".uno:MergeCells"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());

    CPPUNIT_ASSERT(xCellA1->getString().endsWith("test2"));

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());

    xCellA1.set(xTextTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY);

    CPPUNIT_ASSERT(xCellA1->getString().endsWith("test1"));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf39828)
{
    createSwDoc("tdf39828.fodt");
    SwDoc* pDoc = getSwDoc();

    // show changes
    pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete
                                                      | RedlineFlags::ShowInsert);
    CPPUNIT_ASSERT_MESSAGE("redlining should be off",
                           !pDoc->getIDocumentRedlineAccess().IsRedlineOn());
    CPPUNIT_ASSERT_MESSAGE(
        "redlines should be visible",
        IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);

    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount());

    uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY);
    // deleted "1", inserted "2"
    CPPUNIT_ASSERT_EQUAL(u"12"_ustr, xCellA1->getString());
    uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName(u"A3"_ustr), uno::UNO_QUERY);
    // This was 14 (bad sum: 2 + A1, where A1 was 12 instead of the correct 2)
    CPPUNIT_ASSERT_EQUAL(u"4"_ustr, xCellA3->getString());
    uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName(u"A4"_ustr), uno::UNO_QUERY);
    // This was 28 (bad sum: 2 + A1 + A3, where A1 was 12 and A3 was 14)
    CPPUNIT_ASSERT_EQUAL(u"8"_ustr, xCellA4->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146573)
{
    createSwDoc("tdf39828.fodt");
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    // remove redlines, add a footnote, and change the value
    // of the cell with the footnote
    dispatchCommand(mxComponent, u".uno:AcceptAllTrackedChanges"_ustr, {});
    pWrtShell->Right(SwCursorSkipMode::Cells, /*bSelect=*/false, /*nCount=*/1,
                     /*bBasicCall=*/false);
    dispatchCommand(mxComponent, u".uno:InsertFootnote"_ustr, {});
    dispatchCommand(mxComponent, u".uno:PageUp"_ustr, {}); // leave footnote
    pWrtShell->Left(SwCursorSkipMode::Cells, /*bSelect=*/false, /*nCount=*/1, /*bBasicCall=*/false);
    pWrtShell->Left(SwCursorSkipMode::Cells, /*bSelect=*/true, /*nCount=*/1, /*bBasicCall=*/false);
    pWrtShell->Insert(u"100"_ustr);

    // trigger recalculation by leaving the cell
    pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);

    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount());

    uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY);
    // value "100" and footnote index "1"
    CPPUNIT_ASSERT_EQUAL(u"1001"_ustr, xCellA1->getString());
    uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName(u"A3"_ustr), uno::UNO_QUERY);
    // This was 4 (missing recalculation)
    CPPUNIT_ASSERT_EQUAL(u"102"_ustr, xCellA3->getString());
    uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName(u"A4"_ustr), uno::UNO_QUERY);
    // This was 8 (missing recalculation)
    CPPUNIT_ASSERT_EQUAL(u"204"_ustr, xCellA4->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf157132)
{
    createSwDoc("tdf157132.odt");

    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    // Go to cell A2
    pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);

    // Select A2 and A3 and copy
    pWrtShell->Down(/*bSelect=*/true, /*nCount=*/1);

    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});

    // Go to A4 and paste
    pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);

    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
                                                    uno::UNO_QUERY);

    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount());

    uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);

    uno::Reference<text::XTextRange> xCellA2(xTextTable->getCellByName(u"A2"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"2"_ustr, xCellA2->getString());
    uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName(u"A3"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"3"_ustr, xCellA3->getString());
    uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName(u"A4"_ustr), uno::UNO_QUERY);

    // Without the fix in place, this test would have failed with
    // - Expected: 6
    // - Actual  : 2
    CPPUNIT_ASSERT_EQUAL(u"6"_ustr, xCellA4->getString());
    uno::Reference<text::XTextRange> xCellA5(xTextTable->getCellByName(u"A5"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"7"_ustr, xCellA5->getString());

    xTextTable.set(xTables->getByIndex(1), uno::UNO_QUERY);

    xCellA2.set(xTextTable->getCellByName(u"A2"_ustr), uno::UNO_QUERY);

    // tdf#158336: Without the fix in place, this test would have failed with
    // - Expected: 2
    // - Actual  : ** Expression is faulty **
    CPPUNIT_ASSERT_EQUAL(u"2"_ustr, xCellA2->getString());
    xCellA3.set(xTextTable->getCellByName(u"A3"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"3"_ustr, xCellA3->getString());
    xCellA4.set(xTextTable->getCellByName(u"A4"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"6"_ustr, xCellA4->getString());
    xCellA5.set(xTextTable->getCellByName(u"A5"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"7"_ustr, xCellA5->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf147938)
{
    createSwDoc("tdf147938.fodt");

    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
    CPPUNIT_ASSERT_EQUAL(u"Bar\nbaz "_ustr,
                         pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());

    pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
    pWrtShell->TableToText('\t');

    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
    CPPUNIT_ASSERT_EQUAL(u"Bar\nbaz "_ustr,
                         pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    SwInsertTableOptions const opts(SwInsertTableFlags::NONE, 0);
    pWrtShell->TextToTable(opts, '\t', nullptr);

    pWrtShell->Undo();

    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
    CPPUNIT_ASSERT_EQUAL(u"Bar\nbaz "_ustr,
                         pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());

    pWrtShell->Undo();

    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
    CPPUNIT_ASSERT_EQUAL(u"Bar\nbaz "_ustr,
                         pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());

    pWrtShell->Redo();

    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
    CPPUNIT_ASSERT_EQUAL(u"Bar\nbaz "_ustr,
                         pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());

    pWrtShell->Redo();

    pWrtShell->Undo();

    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
    CPPUNIT_ASSERT_EQUAL(u"Bar\nbaz "_ustr,
                         pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());

    pWrtShell->Undo();

    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
    CPPUNIT_ASSERT_EQUAL(u"Bar\nbaz "_ustr,
                         pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148799)
{
    // load a document with table formulas with comma delimiter,
    // but with a document language with default point delimiter
    createSwDoc("tdf148799.docx");
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    // check formula update

    // put cursor in the first table row
    pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
                                                    uno::UNO_QUERY);

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());

    uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);

    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTextTable->getRows()->getCount());

    // These were "** Expression is faulty **"

    uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName(u"D3"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"2.3"_ustr, xCellA1->getString());
    uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName(u"D4"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"2345"_ustr, xCellA3->getString());
    uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName(u"D5"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"23684.5"_ustr, xCellA4->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf151993)
{
    // load a document with table formulas with comma delimiter
    // (with a document language with default comma delimiter)
    createSwDoc("tdf151993.docx");
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    // check formula update

    // put cursor in the first table row
    pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
                                                    uno::UNO_QUERY);

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());

    uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);

    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());

    // This was 0
    uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName(u"A2"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"30"_ustr, xCellA1->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148849)
{
    // load a document with a table and an empty paragraph before the table
    createSwDoc("tdf148849.fodt");
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    // record changes
    pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
                                                      | RedlineFlags::ShowInsert);
    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());
    // hide changes
    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());

    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
                                                    uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());

    // put cursor in the first table row
    pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);

    // delete a table row
    pWrtShell->DeleteRow();

    // check cursor position

    // This was "", because the text cursor jumped to the start of the document
    // after deleting a table row instead of remaining in the next table row
    SwNode& rNode = pWrtShell->GetCursor()->GetPoint()->GetNode();
    CPPUNIT_ASSERT_EQUAL(u"Row 2"_ustr, rNode.GetTextNode()->GetText());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf150576)
{
    // load a document with a table and an empty paragraph before the table
    createSwDoc("tdf148849.fodt");
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    // record changes
    pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
                                                      | RedlineFlags::ShowInsert);
    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());
    // hide changes
    dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
    CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());

    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
                                                    uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());

    // Check deletion of the first row, if the second row deleted already

    // put cursor in the second table row
    pWrtShell->Down(/*bSelect=*/false, /*nCount=*/2);
    SwNode& rNode = pWrtShell->GetCursor()->GetPoint()->GetNode();
    CPPUNIT_ASSERT_EQUAL(u"Row 2"_ustr, rNode.GetTextNode()->GetText());

    // delete the second table row
    pWrtShell->DeleteRow();

    // check cursor position (row 3)
    SwNode& rNode2 = pWrtShell->GetCursor()->GetPoint()->GetNode();
    CPPUNIT_ASSERT_EQUAL(u"Row 3"_ustr, rNode2.GetTextNode()->GetText());

    // put cursor in the first row
    pWrtShell->Up(/*bSelect=*/false, /*nCount=*/1);
    SwNode& rNode3 = pWrtShell->GetCursor()->GetPoint()->GetNode();
    CPPUNIT_ASSERT_EQUAL(u"12"_ustr, rNode3.GetTextNode()->GetText());

    // delete the first row
    pWrtShell->DeleteRow();

    // This was empty (cursor jumped in the start of the document instead of
    // the next not deleted row)
    SwNode& rNode4 = pWrtShell->GetCursor()->GetPoint()->GetNode();
    CPPUNIT_ASSERT_EQUAL(u"Row 3"_ustr, rNode4.GetTextNode()->GetText());

    // Check skipping previous lines

    // restore deleted rows
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    SwNode& rNode5 = pWrtShell->GetCursor()->GetPoint()->GetNode();
    CPPUNIT_ASSERT_EQUAL(u"Row 2"_ustr, rNode5.GetTextNode()->GetText());

    // delete the second row
    pWrtShell->DeleteRow();
    SwNode& rNode7 = pWrtShell->GetCursor()->GetPoint()->GetNode();
    CPPUNIT_ASSERT_EQUAL(u"Row 3"_ustr, rNode7.GetTextNode()->GetText());

    // delete the third, i.e. last row
    pWrtShell->DeleteRow();
    SwNode& rNode8 = pWrtShell->GetCursor()->GetPoint()->GetNode();

    // This was empty (cursor jumped in the start of the document instead of
    // the previous not deleted row)
    CPPUNIT_ASSERT_EQUAL(u"12"_ustr, rNode8.GetTextNode()->GetText());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132603)
{
    createSwDoc();

    uno::Sequence<beans::PropertyValue> aPropertyValues
        = comphelper::InitPropertySequence({ { "Text", uno::Any(u"Comment"_ustr) } });

    dispatchCommand(mxComponent, u".uno:InsertAnnotation"_ustr, aPropertyValues);

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    // Without the fix in place, it would crash here
    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});

    tools::JsonWriter aJsonWriter;
    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->getPostIts(aJsonWriter);
    OString pChar = aJsonWriter.finishAndGetAsOString();
    std::stringstream aStream((std::string(pChar)));
    boost::property_tree::ptree aTree;
    boost::property_tree::read_json(aStream, aTree);
    for (const boost::property_tree::ptree::value_type& rValue : aTree.get_child("comments"))
    {
        const boost::property_tree::ptree& rComment = rValue.second;

        OString aText(rComment.get<std::string>("html"));
        CPPUNIT_ASSERT_EQUAL("<div>Comment</div>"_ostr, aText);
    }
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf117601)
{
    createSwDoc();

    uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
        { { "Rows", uno::Any(sal_Int32(5)) }, { "Columns", uno::Any(sal_Int32(3)) } }));

    dispatchCommand(mxComponent, u".uno:InsertTable"_ustr, aArgs);

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());

    uno::Reference<text::XTextRange> xCellB1(xTextTable->getCellByName(u"B1"_ustr), uno::UNO_QUERY);
    xCellB1->setString(u"test1"_ustr);

    uno::Reference<text::XTextRange> xCellB2(xTextTable->getCellByName(u"B2"_ustr), uno::UNO_QUERY);
    xCellB2->setString(u"test2"_ustr);

    //go to middle row
    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_UP);
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RIGHT);
    Scheduler::ProcessEventsToIdle();

    dispatchCommand(mxComponent, u".uno:EntireColumn"_ustr, {});
    dispatchCommand(mxComponent, u".uno:MergeCells"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());

    CPPUNIT_ASSERT(xCellB1->getString().endsWith("test2"));

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());

    CPPUNIT_ASSERT(xCellB1->getString().endsWith("test1"));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf138130)
{
    createSwDoc("tdf138130.docx");

    CPPUNIT_ASSERT_EQUAL(1, getShapes());
    uno::Reference<drawing::XShape> xShape = getShape(1);

    awt::Point aPos = xShape->getPosition();

    //select shape and change the anchor
    selectShape(1);

    // Without the fix in place, this test would have crashed here
    dispatchCommand(mxComponent, u".uno:SetAnchorToPage"_ustr, {});

    //position has changed
    CPPUNIT_ASSERT(aPos.X < xShape->getPosition().X);
    CPPUNIT_ASSERT(aPos.Y < xShape->getPosition().Y);

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(aPos.X, xShape->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(aPos.Y, xShape->getPosition().Y);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf136385)
{
    createSwDoc("tdf136385.odt");

    CPPUNIT_ASSERT_EQUAL(1, getShapes());
    uno::Reference<drawing::XShape> xShape = getShape(1);

    awt::Point aPos = xShape->getPosition();

    //select shape and change the anchor
    selectShape(1);

    dispatchCommand(mxComponent, u".uno:SetAnchorToPage"_ustr, {});

    //position has changed
    CPPUNIT_ASSERT(aPos.X < xShape->getPosition().X);
    CPPUNIT_ASSERT(aPos.Y < xShape->getPosition().Y);

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    //Without the fix in place, this test would have failed with
    //- Expected: 2447
    //- Actual  : 446
    CPPUNIT_ASSERT_EQUAL(aPos.X, xShape->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(aPos.Y, xShape->getPosition().Y);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf145207)
{
    createSwDoc("tdf145207.odt");

    CPPUNIT_ASSERT_EQUAL(1, getPages());
    CPPUNIT_ASSERT_EQUAL(3, getShapes());

    //select one shape and use the TAB key to iterate over the different shapes
    selectShape(1);

    SwXTextDocument* pTextDoc = getSwTextDoc();
    for (sal_Int32 i = 0; i < 10; ++i)
    {
        // Without the fix in place, this test would have crashed here
        pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
        Scheduler::ProcessEventsToIdle();
    }
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf128782)
{
    createSwDoc("tdf128782.odt");

    CPPUNIT_ASSERT_EQUAL(2, getShapes());
    uno::Reference<drawing::XShape> xShape1 = getShape(1);
    uno::Reference<drawing::XShape> xShape2 = getShape(2);

    awt::Point aPos[2];
    aPos[0] = xShape1->getPosition();
    aPos[1] = xShape2->getPosition();

    //select shape 2 and move it down
    selectShape(2);

    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_DOWN);
    Scheduler::ProcessEventsToIdle();

    CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(aPos[1].X, xShape2->getPosition().X);
    //Y position in shape 2 has changed
    CPPUNIT_ASSERT(aPos[1].Y < xShape2->getPosition().Y);

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(aPos[1].X, xShape2->getPosition().X);
    // Shape2 has come back to the original position
    // without the fix in place, it would have failed
    CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf135623)
{
    createSwDoc("tdf135623.docx");

    CPPUNIT_ASSERT_EQUAL(2, getShapes());
    CPPUNIT_ASSERT_EQUAL(2, getPages());

    uno::Reference<drawing::XShape> xShape1 = getShape(1);
    uno::Reference<drawing::XShape> xShape2 = getShape(2);

    awt::Point aPos[2];
    aPos[0] = xShape1->getPosition();
    aPos[1] = xShape2->getPosition();

    //select shape 1 and move it down
    selectShape(1);

    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_DOWN);
    Scheduler::ProcessEventsToIdle();

    CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
    //Y position in shape 1 has changed
    CPPUNIT_ASSERT(aPos[0].Y < xShape1->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(aPos[1].X, xShape2->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(aPos[1].X, xShape2->getPosition().X);

    // Without the fix in place, this test would have failed here
    // - Expected: 1351
    // - Actual  : 2233
    CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);

    CPPUNIT_ASSERT_EQUAL(2, getPages());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf133490)
{
    createSwDoc("tdf133490.odt");

    CPPUNIT_ASSERT_EQUAL(1, getShapes());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});

    dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(0, getShapes());

    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(1, getShapes());

    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(2, getShapes());

    uno::Reference<drawing::XShape> xShape1 = getShape(1);
    uno::Reference<drawing::XShape> xShape2 = getShape(2);

    awt::Point aPos[2];
    aPos[0] = xShape1->getPosition();
    aPos[1] = xShape2->getPosition();

    //select shape 2 and move it to the right
    selectShape(2);

    SwXTextDocument* pTextDoc = getSwTextDoc();
    for (sal_Int32 i = 0; i < 5; ++i)
    {
        pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RIGHT);
        Scheduler::ProcessEventsToIdle();
    }

    CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
    //X position in shape 2 has changed
    CPPUNIT_ASSERT(aPos[1].X < xShape2->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);

    for (sal_Int32 i = 0; i < 4; ++i)
    {
        dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

        // Without the fix in place, undo action would have changed shape1's position
        // and this test would have failed with
        // - Expected: -139
        // - Actual  : 1194
        CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
        CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
        CPPUNIT_ASSERT(aPos[1].X < xShape2->getPosition().X);
        CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);
    }

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
    // Shape 2 has come back to the original position
    CPPUNIT_ASSERT_EQUAL(aPos[1].X, xShape2->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(1, getShapes());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(0, getShapes());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(1, getShapes());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132637_protectTrackChanges)
{
    createSwDoc("tdf132637_protectTrackChanges.doc");

    // The password should only prevent turning off track changes, not open as read-only
    CPPUNIT_ASSERT(!getSwDocShell()->IsReadOnly());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf127652)
{
    createSwDoc("tdf127652.odt");
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();

    // get a page cursor
    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
        xModel->getCurrentController(), uno::UNO_QUERY);
    uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(),
                                              uno::UNO_QUERY);

    // go to the start of page 4
    xCursor->jumpToPage(4);
    xCursor->jumpToStartOfPage();

    // mark a section that overlaps multiple pages
    pWrtShell->Down(false, 2);
    pWrtShell->Up(true, 5);

    // delete the marked section
    pWrtShell->DelRight();

    // go to the start of page 4
    xCursor->jumpToPage(4);
    xCursor->jumpToStartOfPage();

    // move up to page 3
    pWrtShell->Up(false, 5);

    // check that we are on the third page
    // in the bug one issue was that the cursor was placed incorrectly, so
    // moving up to the previous page would not work any more
    sal_uInt16 assertPage = 3;
    SwCursorShell* pShell(pDoc->GetEditShell());
    CPPUNIT_ASSERT(pShell);
    sal_uInt16 currentPage = pShell->GetPageNumSeqNonEmpty();
    CPPUNIT_ASSERT_EQUAL_MESSAGE("We are on the wrong page!", assertPage, currentPage);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, AtPageTextBoxCrash)
{
    // Load sample file
    createSwDoc("AtPageTextBoxCrash.odt");
    SwDoc* pDoc = getSwDoc();

    // Get the format of the shape
    const auto& rFrmFormats = *pDoc->GetSpzFrameFormats();
    CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1)));
    auto pShape = rFrmFormats.front();
    CPPUNIT_ASSERT(pShape);

    // Add a textbox to the shape
    SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
    auto pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
    CPPUNIT_ASSERT(pTxBxFrm);

    // Change its anchor to page
    uno::Reference<beans::XPropertySet> xShpProps(getShape(1), uno::UNO_QUERY_THROW);
    xShpProps->setPropertyValue(
        u"AnchorType"_ustr, uno::Any(text::TextContentAnchorType::TextContentAnchorType_AT_PAGE));

    // The page anchored objects must not have content anchor
    // unless this will lead to crash later, for example on
    // removing the paragraph where it is anchored to...
    CPPUNIT_ASSERT_EQUAL(RndStdIds::FLY_AT_PAGE, pTxBxFrm->GetAnchor().GetAnchorId());
    CPPUNIT_ASSERT(!pTxBxFrm->GetAnchor().GetAnchorNode());

    // Remove the paragraph where the textframe should be anchored
    // before. Now with the patch it must not crash...
    auto xPara = getParagraph(1);
    xPara->getText()->setString(OUString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf135661)
{
    createSwDoc("tdf135661.odt");

    CPPUNIT_ASSERT_EQUAL(1, getShapes());
    uno::Reference<drawing::XShape> xShape(getShape(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3424), xShape->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1545), xShape->getPosition().Y);

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(0, getShapes());

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(1, getShapes());

    xShape.set(getShape(1), uno::UNO_QUERY);

    //Without the fix in place, the shape position would have been 0,0
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3424), xShape->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1545), xShape->getPosition().Y);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf133477)
{
    if (getDefaultDeviceBitCount() < 24)
        return;
    createSwDoc("tdf133477.fodt");

    // Save the shape to a BMP.
    uno::Reference<drawing::XGraphicExportFilter> xGraphicExporter
        = drawing::GraphicExportFilter::create(m_xContext);
    uno::Reference<lang::XComponent> xSourceDoc(getShape(1), uno::UNO_QUERY);
    xGraphicExporter->setSourceDocument(xSourceDoc);

    SvMemoryStream aStream;
    uno::Reference<io::XOutputStream> xOutputStream(new utl::OStreamWrapper(aStream));
    uno::Sequence<beans::PropertyValue> aDescriptor(comphelper::InitPropertySequence(
        { { "OutputStream", uno::Any(xOutputStream) }, { "FilterName", uno::Any(u"BMP"_ustr) } }));
    xGraphicExporter->filter(aDescriptor);
    aStream.Seek(STREAM_SEEK_TO_BEGIN);

    // Read it back and check the color of the first pixel.
    // (Actually check at one-pixel offset, because imprecise shape positioning may
    // result in blending with background for the first pixel).
    Graphic aGraphic;
    TypeSerializer aSerializer(aStream);
    aSerializer.readGraphic(aGraphic);

    BitmapEx aBitmap = aGraphic.GetBitmapEx();
    CPPUNIT_ASSERT_EQUAL(Color(0, 102, 204), aBitmap.GetPixelColor(1, 1));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf137964)
{
    createSwDoc("tdf137964.odt");
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    CPPUNIT_ASSERT_EQUAL(1, getShapes());
    uno::Reference<drawing::XShape> xShape(getShape(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3579), xShape->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(4090), xShape->getPosition().Y);

    SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
    SdrObject* pObject = pPage->GetObj(1);
    SwContact* pTextBox = static_cast<SwContact*>(pObject->GetUserCall());
    CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_FLYFRMFMT), pTextBox->GetFormat()->Which());

    pWrtShell->SelectObj(Point(), 0, pObject);

    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_UP);
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_LEFT);
    Scheduler::ProcessEventsToIdle();

    // Without the fix in place, the shape would have stayed where it was
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2579), xShape->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3090), xShape->getPosition().Y);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf143244)
{
    createSwDoc("tdf143244.odt");

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());

    uno::Reference<text::XTextRange> xCell(xTextTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(Color(0x009353), getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A2"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A3"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A4"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A5"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A6"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(Color(0xbee3d3), getProperty<Color>(xCell, u"BackColor"_ustr));

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount());

    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});

    xTextTable.set(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());

    dispatchCommand(mxComponent, u".uno:GoUp"_ustr, {});

    SwXTextDocument* pTextDoc = getSwTextDoc();
    for (sal_Int32 i = 0; i < 6; ++i)
    {
        pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
        Scheduler::ProcessEventsToIdle();
    }

    for (sal_Int32 i = 0; i < 5; ++i)
    {
        dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    }

    xTextTable.set(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());

    for (sal_Int32 i = 0; i < 5; ++i)
    {
        dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
    }

    xTextTable.set(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(9), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());

    xCell.set(xTextTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(Color(0x009353), getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A2"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A3"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A4"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A5"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A6"_ustr), uno::UNO_QUERY);

    // Without the fix in place, this test would have failed with
    // - Expected: Color: R:255 G:255 B:255 A:255
    // - Actual  : Color: R:190 G:227 B:211 A:0
    CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A7"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A8"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, u"BackColor"_ustr));

    xCell.set(xTextTable->getCellByName(u"A9"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(Color(0xbee3d3), getProperty<Color>(xCell, u"BackColor"_ustr));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf136715)
{
    createSwDoc("tdf136715.odt");

    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
                                                         uno::UNO_QUERY);
    uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());

    uno::Reference<text::XTextRange> xCell(xTextTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY);
    uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY);
    uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
    uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, u"CharWeight"_ustr));

    xCell.set(xTextTable->getCellByName(u"A2"_ustr), uno::UNO_QUERY);
    xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
    xParaEnum.set(xParaEnumAccess->createEnumeration());
    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xPara, u"CharWeight"_ustr));

    xCell.set(xTextTable->getCellByName(u"A3"_ustr), uno::UNO_QUERY);
    xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
    xParaEnum.set(xParaEnumAccess->createEnumeration());
    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xPara, u"CharWeight"_ustr));

    xCell.set(xTextTable->getCellByName(u"A4"_ustr), uno::UNO_QUERY);
    xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
    xParaEnum.set(xParaEnumAccess->createEnumeration());
    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, u"CharWeight"_ustr));

    dispatchCommand(mxComponent, u".uno:GoDown"_ustr, {});
    dispatchCommand(mxComponent, u".uno:GoDown"_ustr, {});
    dispatchCommand(mxComponent, u".uno:LineDownSel"_ustr, {});
    dispatchCommand(mxComponent, u".uno:DeleteRows"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());

    xCell.set(xTextTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY);
    xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
    xParaEnum.set(xParaEnumAccess->createEnumeration());
    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, u"CharWeight"_ustr));

    xCell.set(xTextTable->getCellByName(u"A2"_ustr), uno::UNO_QUERY);
    xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
    xParaEnum.set(xParaEnumAccess->createEnumeration());
    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, u"CharWeight"_ustr));

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());

    xCell.set(xTextTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY);
    xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
    xParaEnum.set(xParaEnumAccess->createEnumeration());
    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, u"CharWeight"_ustr));

    xCell.set(xTextTable->getCellByName(u"A2"_ustr), uno::UNO_QUERY);
    xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
    xParaEnum.set(xParaEnumAccess->createEnumeration());
    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);

    // Without the fix in place, this test would have failed with
    // - Expected: 100
    // - Actual  : 150
    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xPara, u"CharWeight"_ustr));

    xCell.set(xTextTable->getCellByName(u"A3"_ustr), uno::UNO_QUERY);
    xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
    xParaEnum.set(xParaEnumAccess->createEnumeration());
    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xPara, u"CharWeight"_ustr));

    xCell.set(xTextTable->getCellByName(u"A4"_ustr), uno::UNO_QUERY);
    xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
    xParaEnum.set(xParaEnumAccess->createEnumeration());
    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, u"CharWeight"_ustr));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf138897)
{
    createSwDoc("tdf100018-1.odt");

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
    // this was crashing
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf136740)
{
    createSwDoc();
    css::uno::Reference<css::lang::XMultiServiceFactory> xFact(mxComponent,
                                                               css::uno::UNO_QUERY_THROW);
    css::uno::Reference<css::beans::XPropertySet> xTextDefaults(
        xFact->createInstance(u"com.sun.star.text.Defaults"_ustr), css::uno::UNO_QUERY_THROW);
    const css::uno::Any aOrig = xTextDefaults->getPropertyValue(u"TabStopDistance"_ustr);
    sal_Int32 nDefTab = aOrig.get<sal_Int32>();
    CPPUNIT_ASSERT(nDefTab != 0);

    css::uno::Reference<css::text::XTextRange> const xParagraph(getParagraphOrTable(1),
                                                                css::uno::UNO_QUERY_THROW);
    xParagraph->setString(u"Foo"_ustr);

    CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
    CPPUNIT_ASSERT_EQUAL(u"Foo"_ustr, xParagraph->getString());

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
    dispatchCommand(mxComponent, u".uno:GoToEndOfDoc"_ustr, {});

    const css::uno::Any aNew(nDefTab * 2);
    xTextDefaults->setPropertyValue(u"TabStopDistance"_ustr, aNew);
    // it may become slightly different because of conversions, so get the actual value
    const css::uno::Any aNewCorrected = xTextDefaults->getPropertyValue(u"TabStopDistance"_ustr);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(nDefTab * 2, aNewCorrected.get<sal_Int32>(), 1);

    // Paste special as RTF
    const auto aPropertyValues = comphelper::InitPropertySequence(
        { { "SelectedFormat",
            css::uno::Any(static_cast<sal_uInt32>(SotClipboardFormatId::RTF)) } });
    dispatchCommand(mxComponent, u".uno:ClipboardFormatItems"_ustr, aPropertyValues);

    CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
    CPPUNIT_ASSERT_EQUAL(u"FooFoo"_ustr, xParagraph->getString());

    // Without the fix in place, this would fail with
    //     equality assertion failed
    //     - Expected: <Any: (long) 2501>
    //     - Actual  : <Any: (long) 1251>
    // i.e., pasting RTF would reset the modified default tab stop distance to hardcoded default
    CPPUNIT_ASSERT_EQUAL(aNewCorrected, xTextDefaults->getPropertyValue(u"TabStopDistance"_ustr));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf128106)
{
    createSwDoc("cross_reference_demo_bmk.odt");

    const auto aPropertyValues
        = comphelper::InitPropertySequence({ { "FileName", css::uno::Any(maTempFile.GetURL()) } });
    dispatchCommand(mxComponent, u".uno:NewGlobalDoc"_ustr, aPropertyValues);

    // Use loadFromDesktop instead of loadFromURL to avoid calling mxComponent->dispose()
    // Otherwise it fails with 'DeInitVCL: some top Windows are still alive'
    mxComponent = loadFromDesktop(maTempFile.GetURL());

    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    SwDoc* const pMasterDoc(pWrtShell->GetDoc());
    CPPUNIT_ASSERT_EQUAL(
        size_t(2),
        pMasterDoc->getIDocumentLinksAdministration().GetLinkManager().GetLinks().size());
    // no way to set SwDocShell::m_nUpdateDocMode away from NO_UPDATE ?
    // pMasterDoc->getIDocumentLinksAdministration().UpdateLinks();
    pMasterDoc->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks(
        falsefalse, nullptr, u""_ustr);
    // note: this has called SwGetRefFieldType::UpdateGetReferences()
    SwFieldType constconst pType(
        pMasterDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::GetRef));
    std::vector<SwFormatField*> fields;
    pType->GatherFields(fields);
    CPPUNIT_ASSERT_EQUAL(size_t(6), fields.size());
    std::sort(fields.begin(), fields.end(), [](auto constconst pA, auto constconst pB) {
        SwTextField constconst pHintA(pA->GetTextField());
        SwTextField constconst pHintB(pB->GetTextField());
        // in this document: only 1 field per node
        CPPUNIT_ASSERT(pA == pB || &pHintA->GetTextNode() != &pHintB->GetTextNode());
        return pHintA->GetTextNode().GetIndex() < pHintB->GetTextNode().GetIndex();
    });
    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[0]->GetField()->GetSubType());
    CPPUNIT_ASSERT_EQUAL(
        u"bookmarkchapter1_text"_ustr,
        static_cast<SwGetRefField const*>(fields[0]->GetField())->GetSetRefName().toString());
    CPPUNIT_ASSERT_EQUAL(u"Text"_ustr,
                         static_cast<SwGetRefField const*>(fields[0]->GetField())
                             ->GetExpandedTextOfReferencedTextNode(*pWrtShell->GetLayout()));
    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[1]->GetField()->GetSubType());
    CPPUNIT_ASSERT(
        static_cast<SwGetRefField const*>(fields[1]->GetField())->IsRefToHeadingCrossRefBookmark());
    CPPUNIT_ASSERT_EQUAL(u"Chapter 2"_ustr,
                         static_cast<SwGetRefField const*>(fields[1]->GetField())->GetPar2());
    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[2]->GetField()->GetSubType());
    CPPUNIT_ASSERT_EQUAL(
        u"Bookmarkchapter1"_ustr,
        static_cast<SwGetRefField const*>(fields[2]->GetField())->GetSetRefName().toString());
    CPPUNIT_ASSERT_EQUAL(u"Chapter 1"_ustr,
                         static_cast<SwGetRefField const*>(fields[2]->GetField())->GetPar2());
    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[3]->GetField()->GetSubType());
    CPPUNIT_ASSERT_EQUAL(
        u"bookmarkchapter1_text"_ustr,
        static_cast<SwGetRefField const*>(fields[3]->GetField())->GetSetRefName().toString());
    CPPUNIT_ASSERT_EQUAL(u"Text"_ustr,
                         static_cast<SwGetRefField const*>(fields[3]->GetField())->GetPar2());
    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[4]->GetField()->GetSubType());
    CPPUNIT_ASSERT(
        static_cast<SwGetRefField const*>(fields[4]->GetField())->IsRefToHeadingCrossRefBookmark());
    CPPUNIT_ASSERT_EQUAL(u"Chapter 1.1"_ustr,
                         static_cast<SwGetRefField const*>(fields[4]->GetField())->GetPar2());
    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[5]->GetField()->GetSubType());
    CPPUNIT_ASSERT(
        static_cast<SwGetRefField const*>(fields[5]->GetField())->IsRefToHeadingCrossRefBookmark());
    CPPUNIT_ASSERT_EQUAL(u"Chapter 2"_ustr,
                         static_cast<SwGetRefField const*>(fields[5]->GetField())->GetPar2());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf103612)
{
    createSwGlobalDoc("DUMMY.odm");
    SwDoc* pDoc = getSwDoc();
    CPPUNIT_ASSERT_EQUAL(
        size_t(1), pDoc->getIDocumentLinksAdministration().GetLinkManager().GetLinks().size());
    pDoc->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks(falsefalse, nullptr,
                                                                            u""_ustr);

    xmlDocUniquePtr pLayout = parseLayoutDump();

    assertXPath(pLayout, "/root/page[1]/body/section[1]/txt[1]/SwParaPortion/SwLineLayout[1]",
                "portion", u"Text before section");
    // the inner section and its content was hidden
    assertXPath(pLayout, "/root/page[1]/body/section[2]/txt[1]/SwParaPortion/SwLineLayout[1]",
                "portion", u"Text inside section before ToC");
    assertXPath(pLayout, "/root/page[1]/body/section[3]/txt[1]/SwParaPortion/SwLineLayout[1]",
                "portion", u"Table of Contents");
    assertXPath(pLayout, "/root/page[1]/body/section[4]/txt[1]/SwParaPortion/SwLineLayout[1]",
                "portion", u"First header*1");
    assertXPath(pLayout, "/root/page[1]/body/section[4]/txt[2]/SwParaPortion/SwLineLayout[1]",
                "portion", u"Second header*1");
    assertXPath(pLayout, "/root/page[1]/body/section[5]/txt[2]/SwParaPortion/SwLineLayout[1]",
                "portion", u"Text inside section after ToC");
    assertXPath(pLayout, "/root/page[1]/body/section[6]/txt[1]/SwParaPortion/SwLineLayout[1]",
                "portion", u"Text after section");
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf121119)
{
    createSwGlobalDoc("tdf121119.odm");
    SwDoc* pDoc = getSwDoc();
    CPPUNIT_ASSERT_EQUAL(
        size_t(2), pDoc->getIDocumentLinksAdministration().GetLinkManager().GetLinks().size());
    pDoc->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks(falsefalse, nullptr,
                                                                            u""_ustr);

    uno::Reference<text::XTextGraphicObjectsSupplier> xTextGraphicObjectsSupplier(mxComponent,
                                                                                  uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(
        xTextGraphicObjectsSupplier->getGraphicObjects(), uno::UNO_QUERY);

    // This was 0 (missing images anchored at page)
    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xIndexAccess->getCount());

    uno::Reference<drawing::XShape> xShape(xIndexAccess->getByIndex(0), uno::UNO_QUERY);

    CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_PAGE,
                         getProperty<text::TextContentAnchorType>(xShape, u"AnchorType"_ustr));

    xmlDocUniquePtr pLayout = parseLayoutDump();
    // check page numbers of the objects anchored at page
    assertXPath(pLayout, "/root/page[2]/anchored/fly/SwAnchoredObject", 1);
    assertXPath(pLayout, "/root/page[4]/anchored/fly/SwAnchoredObject", 1);
    assertXPath(pLayout, "/root/page[7]/anchored/fly/SwAnchoredObject", 1);
    assertXPath(pLayout, "/root/page[9]/anchored/fly/SwAnchoredObject", 1);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf97899)
{
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    SwCursorShell* pShell(pDoc->GetEditShell());
    CPPUNIT_ASSERT(pShell);
    SwPaM* pCursor = pShell->GetCursor();

    IDocumentContentOperations& rIDCO(pDoc->getIDocumentContentOperations());

    // Create an Ordered List
    rIDCO.InsertString(*pCursor, u"\ta"_ustr);
    pWrtShell->SplitNode();
    rIDCO.InsertString(*pCursor, u"   b"_ustr);
    pWrtShell->SplitNode();
    rIDCO.InsertString(*pCursor, u"  \t  c"_ustr);

    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:DefaultNumbering"_ustr, {});

    // tdf#109285: RemoveLeadingWhiteSpace from all numbered paragraphs
    getParagraph(1, u"a"_ustr);
    getParagraph(2, u"b"_ustr);
    getParagraph(3, u"c"_ustr);

    // Save it as DOCX & load it again
    saveAndReload(u"Office Open XML Text"_ustr);
    uno::Reference<container::XIndexAccess> xNumberingRules
        = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1),
                                                               u"NumberingRules"_ustr);
    CPPUNIT_ASSERT(xNumberingRules->getCount());
    uno::Sequence<beans::PropertyValue> aNumbering;
    xNumberingRules->getByIndex(0) >>= aNumbering;
    OUString sCharStyleName;
    for (const auto& prop : aNumbering)
    {
        if (prop.Name == "CharStyleName")
        {
            prop.Value >>= sCharStyleName;
            break;
        }
    }
    CPPUNIT_ASSERT(!sCharStyleName.isEmpty());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf40142)
{
    createSwDoc("tdf40142.odt");
    dispatchCommand(mxComponent, u".uno:UpdateAllIndexes"_ustr, {});

    xmlDocUniquePtr pLayout = parseLayoutDump();
    // Without the fix in place, this test would have failed with
    // - Expected: 2
    // - Actual  : 4
    assertXPath(pLayout, "/root/page[1]/body/section[2]/txt", 2);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf151462)
{
    createSwDoc("tdf151462.odt");
    dispatchCommand(mxComponent, u".uno:UpdateAllIndexes"_ustr, {});

    xmlDocUniquePtr pLayout = parseLayoutDump();
    // Without the fix in place, there would be just the first index entry
    assertXPath(pLayout,
                "/root/page[1]/body/txt[2]/anchored/fly/section/txt[1]/SwParaPortion/"
                "SwLineLayout[1]/SwLinePortion[1]",
                "portion", u"sub one");
    assertXPath(pLayout,
                "/root/page[1]/body/txt[2]/anchored/fly/section/txt[2]/SwParaPortion/"
                "SwLineLayout[1]/SwLinePortion[1]",
                "portion", u"sub two");
    assertXPath(pLayout,
                "/root/page[1]/body/txt[2]/anchored/fly/section/txt[3]/SwParaPortion/"
                "SwLineLayout[1]/SwLinePortion[1]",
                "portion", u"sub three");

    // Without the fix in place, there would be just the first index entry
    assertXPath(pLayout,
                "/root/page[1]/body/txt[6]/anchored/fly/section/txt[1]/SwParaPortion/"
                "SwLineLayout[1]/SwLinePortion[1]",
                "portion", u"another sub one");
    assertXPath(pLayout,
                "/root/page[1]/body/txt[6]/anchored/fly/section/txt[2]/SwParaPortion/"
                "SwLineLayout[1]/SwLinePortion[1]",
                "portion", u"another sub two");
    assertXPath(pLayout,
                "/root/page[1]/body/txt[6]/anchored/fly/section/txt[3]/SwParaPortion/"
                "SwLineLayout[1]/SwLinePortion[1]",
                "portion", u"another sub three");
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf153636)
{
    createSwDoc("tdf153636.odt");
    dispatchCommand(mxComponent, u".uno:UpdateAllIndexes"_ustr, {});
    saveAndReload(u"writer8"_ustr);

    xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
    CPPUNIT_ASSERT(pXmlDoc);

    for (int i = 1; i <= 3; i += 2)
    {
        const OUString frameStyleName
            = getXPath(pXmlDoc,
                       "/office:document-content/office:body/office:text/"
                       "text:user-index[@text:name='User-Defined1']/text:index-body/text:p["
                           + OString::number(i) + "]",
                       "style-name");
        const OUString tableStyleName
            = getXPath(pXmlDoc,
                       "/office:document-content/office:body/office:text/"
                       "text:user-index[@text:name='User-Defined1']/text:index-body/text:p["
                           + OString::number(i + 1) + "]",
                       "style-name");

        // Without the fix in place, the frame and table indentation would differ
        CPPUNIT_ASSERT_EQUAL(frameStyleName, tableStyleName);
    }
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf157129)
{
    // Unit test for tdf#157129
    // Test to see if cursor moves to the end after paste

    // First document containing test data
    createSwDoc("tdf157129.doc");
    CPPUNIT_ASSERT_EQUAL(5, getParagraphs());
    // Copy data from first document
    dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
    dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});

    // Create a new document
    createSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    CPPUNIT_ASSERT_EQUAL(1, getParagraphs());

    // Paste data from first document
    dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
    CPPUNIT_ASSERT_EQUAL(5, getParagraphs());

    // Save cursor position after paste occurs
    SwPosition aCursorPosPaste(*pWrtShell->GetCursor()->GetPoint());

    // Move cursor position to the end
    pWrtShell->SttEndDoc(false); //bStart = false

    // Save cursor position at end
    SwPosition aCursorPosEnd(*pWrtShell->GetCursor()->GetPoint());

    // Assert the cursor position after paste is at the end
    // Without the test in place, the cursor position is at the beginning of the document
    // - Expected : SwPosition (node 18, offset 0)
    // - Actual : SwPosition (node 6, offset 0)
    CPPUNIT_ASSERT_EQUAL(aCursorPosEnd, aCursorPosPaste);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testCursorPositionAfterUndo)
{
    createSwDoc("cursor_position_after_undo.odt");
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    // switch on "Outline Folding" mode
    dispatchCommand(mxComponent, u".uno:ShowOutlineContentVisibilityButton"_ustr, {});
    CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton());

    // move the cursor to the beginning of the 3rd word in the 3rd paragraph, "tincidunt"
    pWrtShell->FwdPara();
    pWrtShell->FwdPara();
    pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 16, /*bBasicCall=*/false);

    // select the word
    dispatchCommand(mxComponent, u".uno:SelectWord"_ustr, {});

    // check the word is select
    SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
    CPPUNIT_ASSERT_EQUAL(u"tincidunt"_ustr, pShellCursor->GetText());

    // remember the cursor position for comparison
    SwPosition aCursorPos(*pWrtShell->GetCursor()->GetPoint());

    // delete the selected word
    pWrtShell->Delete();

    // undo delete
    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    // without the fix in place, the cursor would have been set to the start of the outline node
    // - Expected: SwPosition (node 11, offset 25)
    // - Actual  : SwPosition (node 9, offset 0)
    CPPUNIT_ASSERT_EQUAL(aCursorPos, *pWrtShell->GetCursor()->GetPoint());

    // switch off "Outline Folding" mode
    dispatchCommand(mxComponent, u".uno:ShowOutlineContentVisibilityButton"_ustr, {});
    CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf73483)
{
    // Given a document with a first paragraph having a manually set page break with page style
    createSwDoc("pageBreakWithPageStyle.fodt");
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    CPPUNIT_ASSERT_EQUAL(u"Right Page"_ustr, pWrtShell->GetCurPageStyle().toString());

    dispatchCommand(mxComponent, u".uno:ResetAttributes"_ustr,
                    {}); // Ctrl+M "Clear Direct Formatting"
    // Make sure that clearing direct formatting doesn't clear the page style
    CPPUNIT_ASSERT_EQUAL(u"Right Page"_ustr, pWrtShell->GetCurPageStyle().toString());

    // Make sure that the page break with page style survives ODF save-and-reload
    saveAndReload(u"writer8"_ustr);

    xmlDocUniquePtr pXml = parseExport(u"content.xml"_ustr);
    CPPUNIT_ASSERT(pXml);
    OUString para_style_name
        = getXPath(pXml, "/office:document-content/office:body/office:text/text:p""style-name");
    // Without the fix in place, this would fail
    CPPUNIT_ASSERT(!para_style_name.equalsIgnoreAsciiCase("Standard"));

    OString para_style_path
        = "/office:document-content/office:automatic-styles/style:style[@style:name='"
          + para_style_name.toUtf8() + "']";
    assertXPath(pXml, para_style_path, "family", u"paragraph");
    // Without the fix in place, the autostyle had no parent
    assertXPath(pXml, para_style_path, "parent-style-name", u"Standard");
    assertXPath(pXml, para_style_path, "master-page-name", u"Right_20_Page");
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf62032ApplyStyle)
{
    createSwDoc("tdf62032_apply_style.odt");
    SwWrtShell* pWrtSh = getSwDocShell()->GetWrtShell();

    pWrtSh->Down(/*bSelect=*/false);

    uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence({
        { "Style", uno::Any(u"A 2"_ustr) },
        { "FamilyName", uno::Any(u"ParagraphStyles"_ustr) },
    });
    dispatchCommand(mxComponent, u".uno:StyleApply"_ustr, aPropertyValues);

    // Without the fix in place, it fails with:
    // - Expected: 1.1
    // - Actual  : 2
    CPPUNIT_ASSERT_EQUAL(u"1.1"_ustr,
                         getProperty<OUString>(getParagraph(2), u"ListLabelString"_ustr).trim());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf156560)
{
    createSwDoc("tdf156560.docx");

    uno::Reference<beans::XPropertySet> xPageStyle(
        getStyles(u"PageStyles"_ustr)->getByName(u"Standard"_ustr), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));

    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_MOD1 | KEY_PAGEUP);

    // Insert header
    // Without the fix in place, this test would have got SIGABRT here
    dispatchCommand(mxComponent, u".uno:InsertHeader"_ustr, {});
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf158459)
{
    createSwDoc("tdf158459_tracked_changes_across_nodes.fodt");
    SwDoc* pDoc = getSwDoc();

    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell);
    pWrtShell->FwdPara(); // Skip first paragraph
    pWrtShell->EndOfSection(true); // Select everything to the end

    SwDoc aClipboard;
    pWrtShell->Copy(aClipboard); // This must not crash

    pWrtShell->SelAll();
    pWrtShell->Delete();
    pWrtShell->Paste(aClipboard); // Replace everything with the copied stuff

    SwNodes& rNodes = pDoc->GetNodes();
    SwNodeIndex aIdx(rNodes.GetEndOfExtras());
    SwContentNode* pContentNode = SwNodes::GoNext(&aIdx);
    CPPUNIT_ASSERT(pContentNode);
    SwTextNode* pTextNode = pContentNode->GetTextNode();
    CPPUNIT_ASSERT(pTextNode);
    // Check that deleted parts (paragraph break, "c", "e") haven't been pasted
    CPPUNIT_ASSERT_EQUAL(u"abdf"_ustr, pTextNode->GetText());
}

// end of anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5 in Prozent
C=89 H=91 G=89

¤ Dauer der Verarbeitung: 0.47 Sekunden  (vorverarbeitet am  2026-04-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge