Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sw/qa/extras/uiwriter/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 132 kB image not shown  

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 ."_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
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=92 H=97 G=94

¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet)  ¤

*© 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.