summaryrefslogtreecommitdiffstats
path: root/sw/qa/extras/uiwriter/uiwriter8.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/qa/extras/uiwriter/uiwriter8.cxx')
-rw-r--r--sw/qa/extras/uiwriter/uiwriter8.cxx2922
1 files changed, 2922 insertions, 0 deletions
diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx b/sw/qa/extras/uiwriter/uiwriter8.cxx
new file mode 100644
index 0000000000..4fa027b051
--- /dev/null
+++ b/sw/qa/extras/uiwriter/uiwriter8.cxx
@@ -0,0 +1,2922 @@
+/* -*- 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 <sfx2/linkmgr.hxx>
+
+#include <wrtsh.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>
+
+/// 8th set of tests asserting the behavior of Writer user interface shells.
+class SwUiWriterTest8 : public SwModelTestBase
+{
+public:
+ SwUiWriterTest8()
+ : SwModelTestBase("/sw/qa/extras/uiwriter/data/")
+ {
+ }
+};
+
+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, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:Cut", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
+
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
+
+ // without the fix, it crashes
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ 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]"_ostr, "id"_ostr);
+ OUString const sectionLower
+ = getXPath(pXmlDoc, "/root/page[1]/body/section[7]"_ostr, "lower"_ostr);
+ OUString const textId
+ = getXPath(pXmlDoc, "/root/page[1]/body/section[7]/txt[1]"_ostr, "id"_ostr);
+ OUString const textUpper
+ = getXPath(pXmlDoc, "/root/page[1]/body/section[7]/txt[1]"_ostr, "upper"_ostr);
+ 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, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:Cut", {});
+ CPPUNIT_ASSERT_EQUAL(0, getShapes());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ //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, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:Cut", {});
+
+ CPPUNIT_ASSERT_EQUAL(0, getShapes());
+
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ //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();
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->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("Table1"));
+ uno::Reference<text::XTextTable> xTable1(xTableNames->getByName("Table1"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());
+
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+
+ // This was 3 (deleting the already deleted row with change tracking)
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+ // 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, ".uno:AcceptAllTrackedChanges", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
+
+ // Undo AcceptAllTrackedChanges and DeleteRows
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ // now only the second table deleted by AcceptAllTrackedChanges
+ dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {});
+ 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();
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ // enable redlining
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+ pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+ // hide changes
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
+
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+
+ // 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"_ostr, 1);
+
+ // check it in Show Changes mode
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pWrtShell->GetLayout()->IsHideRedlines());
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // 2 rows are visible now
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 2);
+
+ // check it in Hide Changes mode again
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // only a single row is visible again
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 1);
+
+ // tdf#148227 check Undo of tracked table row deletion
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // This was 1
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 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();
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ // enable redlining
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+ pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+ // hide changes
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ 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, ".uno:DeleteTable", {});
+
+ // tracked table deletion
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
+
+ // hidden table
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//tab"_ostr, 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, ".uno:Delete", {});
+
+ // undo frame deletion
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ // undo tracked table deletion
+
+ // This resulted crashing
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+}
+
+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();
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ // enable redlining
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+ pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+ // hide changes
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
+
+ dispatchCommand(mxComponent, ".uno:DeleteTable", {});
+
+ // 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"_ostr, 0);
+
+ // check it in Show Changes mode
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pWrtShell->GetLayout()->IsHideRedlines());
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // 2 rows are visible now
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 2);
+
+ // check it in Hide Changes mode again
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // no visible row again
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 0);
+
+ // tdf#148228 check Undo of tracked table deletion
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // This was 0
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 2);
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf153819)
+{
+ // copy a table before a deleted table in Hide Changes mode
+ createSwDoc("tdf153819.fodt");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ // hide changes
+ CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
+
+ dispatchCommand(mxComponent, ".uno:SelectTable", {});
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+ dispatchCommand(mxComponent, ".uno:GoDown", {});
+
+ // Without the fix in place, this test would have crashed here
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ // FIXME: Show Changes, otherwise ~SwTableNode() would have crashed
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+}
+
+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();
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ // enable redlining
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+ pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+ // hide changes
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
+
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+
+ // 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"_ostr, 1);
+
+ // check it in Show Changes mode
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(!pWrtShell->GetLayout()->IsHideRedlines());
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // 2 rows are visible now
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 2);
+
+ // check it in Hide Changes mode again
+
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+ CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // only a single row is visible again
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 1);
+
+ // tdf#148227 check Reject All of tracked table row deletion
+
+ dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // This was 1
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 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");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ // select the table, and copy it into at paragraph start of cell "A2"
+
+ dispatchCommand(mxComponent, ".uno:SelectTable", {});
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+ // remove the selection and positionate the cursor at beginning of A2
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ 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"_ostr, 3);
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout"_ostr,
+ "portion"_ostr, "hello");
+
+ // Undo
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // 2 rows again, no copied text content
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/SwParaPortion"_ostr, 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("Some text...");
+ pWrtShell->SplitNode();
+ Scheduler::ProcessEventsToIdle();
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt"_ostr, 2);
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/SwParaPortion/SwLineLayout"_ostr,
+ "portion"_ostr, "Some text...");
+ // the empty paragraph in A2
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[2]/SwParaPortion"_ostr, 0);
+
+ // insert the table, as a nested one in cell "A2"
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 2);
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab/row"_ostr, 2);
+
+ // Undo
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // 2 rows again, no copied text content
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 2);
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/SwParaPortion/SwLineLayout"_ostr,
+ "portion"_ostr, "Some text...");
+
+ // copy the 2-row table into the fist paragraph of cell "A2",
+ // but not at paragraph start (changed behaviour)
+
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ pWrtShell->Insert("and some text again in the first paragraph to be sure...");
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ discardDumpedLayout();
+ 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"_ostr, 3);
+ // This was "Some text..." with a nested table
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout"_ostr,
+ "portion"_ostr, "hello");
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148791)
+{
+ // test Paste as Rows Above with centered table alignment
+
+ // load a 2-row table
+ createSwDoc("tdf116789.fodt");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ // select and copy the table, and Paste As Rows Above
+
+ dispatchCommand(mxComponent, ".uno:SelectTable", {});
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+ // 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, ".uno:PasteRowsBefore", {});
+
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ // Paste as Rows Above results 4-row table with default table alignment
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 4);
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab/row[1]/cell[1]/txt/SwParaPortion/SwLineLayout"_ostr,
+ "portion"_ostr, "hello");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab/row[3]/cell[1]/txt/SwParaPortion/SwLineLayout"_ostr,
+ "portion"_ostr, "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, "HoriOrient"));
+
+ //CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xTextTable, "TableTemplateName"));
+ uno::Reference<beans::XPropertySet> xTableProps(xTextTable, uno::UNO_QUERY_THROW);
+
+ xTableProps->setPropertyValue("HoriOrient", uno::Any(text::HoriOrientation::CENTER));
+
+ CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER,
+ getProperty<sal_Int16>(xTextTable, "HoriOrient"));
+
+ dispatchCommand(mxComponent, ".uno:SelectTable", {});
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+ // 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, ".uno:PasteRowsBefore", {});
+
+ discardDumpedLayout();
+ 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"_ostr, 8);
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab/row[1]/cell[1]/txt/SwParaPortion/SwLineLayout"_ostr,
+ "portion"_ostr, "hello");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab/row[3]/cell[1]/txt/SwParaPortion/SwLineLayout"_ostr,
+ "portion"_ostr, "hello");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab/row[5]/cell[1]/txt/SwParaPortion/SwLineLayout"_ostr,
+ "portion"_ostr, "hello");
+ assertXPath(pXmlDoc,
+ "/root/page[1]/body/tab/row[7]/cell[1]/txt/SwParaPortion/SwLineLayout"_ostr,
+ "portion"_ostr, "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, ".uno:PasteNestedTable", {});
+ dispatchCommand(mxComponent, ".uno:SelectTable", {});
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+ // 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, ".uno:PasteRowsBefore", {});
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // rows of the nested table doesn't effect row number of the main table
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 16);
+ // there are two nested tables after the paste
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab"_ostr, 2);
+
+ // tdf#64902 add a test case for repeated table headings
+
+ xTableProps->setPropertyValue("RepeatHeadline", uno::Any(true));
+ CPPUNIT_ASSERT(getProperty<bool>(xTextTable, "RepeatHeadline"));
+
+ xTableProps->setPropertyValue("HeaderRowCount", uno::Any(sal_Int32(3)));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), getProperty<sal_Int32>(xTextTable, "HeaderRowCount"));
+
+ dispatchCommand(mxComponent, ".uno:SelectTable", {});
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+ // 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, ".uno:PasteRowsBefore", {});
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ // repeating table header (and its thead/tbody indentation) doesn't effect row number
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 32);
+ // there are two nested tables after the paste
+ assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab"_ostr, 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, ".uno:DefaultBullet", aArgs);
+
+ uno::Sequence<beans::PropertyValue> aArgs2(comphelper::InitPropertySequence(
+ { { "Param", uno::Any(OUString("NewNumberingStyle")) },
+ { "Family", uno::Any(static_cast<sal_Int16>(SfxStyleFamily::Pseudo)) } }));
+
+ // New Style from selection
+ dispatchCommand(mxComponent, ".uno:StyleNewByExample", aArgs2);
+
+ // Without the fix in place, this test would have failed here
+ saveAndReload("Office Open XML Text");
+
+ xmlDocUniquePtr pXmlStyles = parseExport("word/styles.xml");
+ assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='NewNumberingStyle']/w:qFormat"_ostr, 1);
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf130629)
+{
+ createSwDoc();
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+
+ uno::Sequence<beans::PropertyValue> aArgs(
+ comphelper::InitPropertySequence({ { "KeyModifier", uno::Any(KEY_MOD1) } }));
+
+ dispatchCommand(mxComponent, ".uno:BasicShapes.diamond", aArgs);
+
+ CPPUNIT_ASSERT_EQUAL(1, getShapes());
+
+ // Undo twice
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(0, getShapes());
+
+ // Shape toolbar is active, use ESC before inserting a new shape
+ pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_ESCAPE);
+ Scheduler::ProcessEventsToIdle();
+
+ // Without the fix in place, this test would have crashed here
+ dispatchCommand(mxComponent, ".uno:BasicShapes.diamond", 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();
+ SwDoc* const pDoc = getSwDoc();
+ SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtSh);
+
+ pWrtSh->Insert("Hello World");
+
+ // 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(OUString("writer_pdf_Export")) },
+ { "FilterData", uno::Any(aFilterData) },
+ { "URL", uno::Any(maTempFile.GetURL()) } }));
+
+ // Without the fix in place, this test would have crashed here
+ dispatchCommand(mxComponent, ".uno:ExportToPDF", 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(OUString("World"), sText);
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf152575)
+{
+ 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(OUString("writer_pdf_Export")) },
+ { "FilterData", uno::Any(aFilterData) },
+ { "URL", uno::Any(maTempFile.GetURL()) } }));
+
+ // Without the fix in place, this test would have crashed here
+ dispatchCommand(mxComponent, ".uno:ExportToPDF", 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(51, pPdfPage->getObjectCount());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf140731)
+{
+ createSwDoc();
+ SwDoc* const pDoc = getSwDoc();
+ SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtSh);
+
+ pWrtSh->Insert("Lorem");
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+
+ 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, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+ }
+
+ dispatchCommand(mxComponent, ".uno:GoToStartOfDoc", {});
+
+ // Format->Text operations on small selections (which would generate <~500 redlines)
+ // changetracking still working
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+
+ SwCursorShell* pShell(pDoc->GetEditShell());
+
+ pShell->SelectTextModel(1, 500);
+
+ dispatchCommand(mxComponent, ".uno:ChangeCaseToTitleCase", {});
+
+ SwEditShell* const pEditShell(pDoc->GetEditShell());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(120),
+ pEditShell->GetRedlineCount());
+
+ //Removing all the redlines.
+ dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(0), pEditShell->GetRedlineCount());
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:ChangeCaseToTitleCase", {});
+
+ // 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, ".uno:ChangeCaseToUpper", {});
+
+ CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("LOREM IPSUM DOLOR SIT AMET"));
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf116315)
+{
+ createSwDoc();
+ SwDoc* const pDoc = getSwDoc();
+ SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtSh);
+
+ pWrtSh->Insert("This is a test");
+ pWrtSh->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 4, /*bBasicCall=*/false);
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ 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(OUString("This is a Test"), getParagraph(1)->getString());
+
+ pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
+ Scheduler::ProcessEventsToIdle();
+
+ // Sentence Case
+ // Without the fix in place, this test would have failed with
+ // - Expected: This is a Test
+ // - Actual : This is a TEST
+ CPPUNIT_ASSERT_EQUAL(OUString("This is a Test"), getParagraph(1)->getString());
+
+ pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
+ Scheduler::ProcessEventsToIdle();
+
+ // Upper Case
+ CPPUNIT_ASSERT_EQUAL(OUString("This is a TEST"), getParagraph(1)->getString());
+
+ pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
+ Scheduler::ProcessEventsToIdle();
+
+ // Lower Case
+ CPPUNIT_ASSERT_EQUAL(OUString("This is a test"), getParagraph(1)->getString());
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf144364)
+{
+ createSwDoc();
+ SwDoc* const pDoc = getSwDoc();
+ SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtSh);
+
+ // expands autotext (via F3)
+ pWrtSh->Insert("AR");
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F3);
+ Scheduler::ProcessEventsToIdle();
+
+ // was ...'letter of <placeholder:"November 21, 2004":"Click placeholder and overwrite">'
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("We hereby acknowledge the receipt of your letter of <November 21, 2004>."),
+ getParagraph(1)->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146248)
+{
+ createSwDoc("tdf146248.docx");
+
+ uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, "HeaderIsOn"));
+
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+ // Delete the header
+ pWrtShell->ChangeHeaderOrFooter(u"Default Page Style", true, false, false);
+
+ CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPageStyle, "HeaderIsOn"));
+
+ // Without the fix in place, this test would have crashed here
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, "HeaderIsOn"));
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf152964)
+{
+ createSwDoc();
+
+ dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+ dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+
+ uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
+ { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));
+
+ dispatchCommand(mxComponent, ".uno:InsertTable", 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_EQUAL(static_cast<SwRedlineTable::size_type>(1), pEditShell->GetRedlineCount());
+ dispatchCommand(mxComponent, ".uno:GoDown", {});
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount());
+
+ // Without the fix in place, this test would have crashed here
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), pEditShell->GetRedlineCount());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(0), pEditShell->GetRedlineCount());
+
+ dispatchCommand(mxComponent, ".uno:Redo", {});
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), pEditShell->GetRedlineCount());
+ dispatchCommand(mxComponent, ".uno:Redo", {});
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf107427)
+{
+ createSwDoc();
+
+ dispatchCommand(mxComponent,
+ ".uno:InsertPageHeader?PageStyle:string=Default%20Page%20Style&On:bool=true",
+ {});
+ uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
+ { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));
+
+ dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
+
+ xmlDocUniquePtr pLayout = parseLayoutDump();
+ assertXPath(pLayout, "/root/page[1]/header/tab/row"_ostr, 2);
+
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ // Delete the header
+ pWrtShell->ChangeHeaderOrFooter(u"Default Page Style", true, false, false);
+
+ discardDumpedLayout();
+ pLayout = parseLayoutDump();
+ assertXPath(pLayout, "/root/page[1]/header"_ostr, 0);
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ discardDumpedLayout();
+ pLayout = parseLayoutDump();
+ assertXPath(pLayout, "/root/page[1]/header/tab/row"_ostr, 2);
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf141613)
+{
+ createSwDoc();
+ SwDoc* const pDoc = getSwDoc();
+ SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtSh);
+
+ pWrtSh->Insert("Test");
+
+ dispatchCommand(mxComponent,
+ ".uno:InsertPageHeader?PageStyle:string=Default%20Page%20Style&On:bool=true",
+ {});
+
+ uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, "HeaderIsOn"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(1)->getString());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPageStyle, "HeaderIsOn"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(1)->getString());
+
+ // Without the fix in place, this test would have crashed here
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ CPPUNIT_ASSERT_EQUAL(OUString(""), 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("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY);
+
+ uno::Reference<text::XTextContent> xTextContent(xTextGraphic, uno::UNO_QUERY);
+
+ uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"),
+ uno::UNO_QUERY);
+
+ xPageStyle->setPropertyValue("HeaderIsOn", uno::Any(true));
+
+ uno::Reference<text::XText> xHeader(
+ getProperty<uno::Reference<text::XText>>(xPageStyle, "HeaderText"));
+ CPPUNIT_ASSERT(xHeader.is());
+ uno::Reference<text::XTextCursor> xHeaderCursor(xHeader->createTextCursor());
+
+ xHeader->insertTextContent(xHeaderCursor, xTextContent, false);
+
+ CPPUNIT_ASSERT_EQUAL(1, getShapes());
+
+ xPageStyle->setPropertyValue("HeaderIsOn", uno::Any(false));
+
+ CPPUNIT_ASSERT_EQUAL(0, getShapes());
+
+ xPageStyle->setPropertyValue("FooterIsOn", uno::Any(true));
+
+ uno::Reference<text::XText> xFooter(
+ getProperty<uno::Reference<text::XText>>(xPageStyle, "FooterText"));
+ CPPUNIT_ASSERT(xFooter.is());
+ uno::Reference<text::XTextCursor> xFooterCursor(xFooter->createTextCursor());
+
+ xTextGraphic.set(xFactory->createInstance("com.sun.star.text.TextGraphicObject"),
+ uno::UNO_QUERY);
+
+ xTextContent.set(xTextGraphic, uno::UNO_QUERY);
+
+ xFooter->insertTextContent(xFooterCursor, xTextContent, false);
+
+ CPPUNIT_ASSERT_EQUAL(1, getShapes());
+
+ xPageStyle->setPropertyValue("FooterIsOn", uno::Any(false));
+
+ CPPUNIT_ASSERT_EQUAL(0, getShapes());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf133358)
+{
+ createSwDoc();
+ SwDoc* const pDoc = getSwDoc();
+ SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtSh);
+
+ pWrtSh->Insert("Test");
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(1)->getString());
+
+ uno::Reference<beans::XPropertyState> xParagraph(getParagraph(1), uno::UNO_QUERY);
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xParagraph, "ParaLeftMargin"));
+
+ dispatchCommand(mxComponent, ".uno:IncrementIndent", {});
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1251), getProperty<sal_Int32>(xParagraph, "ParaLeftMargin"));
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xParagraph, "ParaLeftMargin"));
+
+ // Without the fix in place, this test would have crashed here
+ dispatchCommand(mxComponent, ".uno:Redo", {});
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1251), getProperty<sal_Int32>(xParagraph, "ParaLeftMargin"));
+}
+
+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, ".uno:InsertTable", 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(OUString(""), getProperty<OUString>(xTextTable, "TableTemplateName"));
+ uno::Reference<beans::XPropertySet> xTableProps(xTextTable, uno::UNO_QUERY_THROW);
+ xTableProps->setPropertyValue("TableTemplateName", uno::Any(OUString("Default Style")));
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Default Style"),
+ getProperty<OUString>(xTextTable, "TableTemplateName"));
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+ dispatchCommand(mxComponent, ".uno:GoDown", {});
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount());
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Default Style"),
+ getProperty<OUString>(xTextTable, "TableTemplateName"));
+
+ 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(OUString("Default Style"),
+ getProperty<OUString>(xTextTable2, "TableTemplateName"));
+}
+
+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, ".uno:InsertTable", 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, ".uno:DeleteRows", {});
+
+ 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, ".uno:Undo", {});
+
+ 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, ".uno:Undo", {});
+
+ //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, ".uno:InsertTable", 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, ".uno:DeleteTable", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ 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"_ostr, 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, testTdf121546)
+{
+ createSwDoc("tdf121546.odt");
+
+ CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString());
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:Cut", {});
+
+ CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
+
+ // Create a new document
+ createSwDoc();
+
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString());
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:Cut", {});
+
+ CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+
+ // Without the fix in place, this test would have crashed here
+ 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(OUString("AAAAAA"), getParagraph(1)->getString());
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:Cut", {});
+
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getParagraph(1)->getString());
+
+ // Without the fix in place, this test would have crashed
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ CPPUNIT_ASSERT_EQUAL(OUString("AAAAAA"), getParagraph(1)->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf134626)
+{
+ createSwDoc("tdf134626.odt");
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString());
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+
+ // Create a new document
+ createSwDoc();
+ pDoc = getSwDoc();
+ pWrtShell = pDoc->GetDocShell()->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, ".uno:Paste", {});
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString());
+
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ CPPUNIT_ASSERT_EQUAL(OUString("AppleApple"), getParagraph(1)->getString());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getParagraph(1)->getString());
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf139566)
+{
+ createSwDoc();
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtSh = pDoc->GetDocShell()->GetWrtShell();
+
+ uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
+ { { "Rows", uno::Any(sal_Int32(1)) }, { "Columns", uno::Any(sal_Int32(1)) } }));
+
+ dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
+
+ // Move the cursor outside the table
+ pWrtSh->Down(/*bSelect=*/false);
+
+ pWrtSh->Insert("Test");
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(2)->getString());
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+
+ uno::Reference<frame::XFrames> xFrames = mxDesktop->getFrames();
+ sal_Int32 nFrames = xFrames->getCount();
+
+ // Create a second window so the first window looses focus
+ dispatchCommand(mxComponent, ".uno:NewWindow", {});
+
+ CPPUNIT_ASSERT_EQUAL(nFrames + 1, xFrames->getCount());
+
+ dispatchCommand(mxComponent, ".uno:CloseWin", {});
+
+ 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, ".uno:InsertTable", 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, ".uno:SelectTable", {});
+ dispatchCommand(mxComponent, ".uno:InsertRowsBefore", {});
+
+ 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, ".uno:Undo", {});
+
+ 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, ".uno:InsertTable", 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("A1"), uno::UNO_QUERY);
+ xCellA1->setString("test1");
+
+ uno::Reference<text::XTextRange> xCellA2(xTextTable->getCellByName("A2"), uno::UNO_QUERY);
+ xCellA2->setString("test2");
+
+ dispatchCommand(mxComponent, ".uno:EntireColumn", {});
+ dispatchCommand(mxComponent, ".uno:MergeCells", {});
+
+ 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, ".uno:Undo", {});
+
+ 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("A1"), 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("A1"), uno::UNO_QUERY);
+ // deleted "1", inserted "2"
+ CPPUNIT_ASSERT_EQUAL(OUString("12"), xCellA1->getString());
+ uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
+ // This was 14 (bad sum: 2 + A1, where A1 was 12 instead of the correct 2)
+ CPPUNIT_ASSERT_EQUAL(OUString("4"), xCellA3->getString());
+ uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
+ // This was 28 (bad sum: 2 + A1 + A3, where A1 was 12 and A3 was 14)
+ CPPUNIT_ASSERT_EQUAL(OUString("8"), xCellA4->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146573)
+{
+ createSwDoc("tdf39828.fodt");
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+ // remove redlines, add a footnote, and change the value
+ // of the cell with the footnote
+ dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {});
+ pWrtShell->Right(SwCursorSkipMode::Cells, /*bSelect=*/false, /*nCount=*/1,
+ /*bBasicCall=*/false);
+ dispatchCommand(mxComponent, ".uno:InsertFootnote", {});
+ dispatchCommand(mxComponent, ".uno:PageUp", {}); // leave footnote
+ pWrtShell->Left(SwCursorSkipMode::Cells, /*bSelect=*/false, /*nCount=*/1, /*bBasicCall=*/false);
+ pWrtShell->Left(SwCursorSkipMode::Cells, /*bSelect=*/true, /*nCount=*/1, /*bBasicCall=*/false);
+ pWrtShell->Insert("100");
+
+ // 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("A1"), uno::UNO_QUERY);
+ // value "100" and footnote index "1"
+ CPPUNIT_ASSERT_EQUAL(OUString("1001"), xCellA1->getString());
+ uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
+ // This was 4 (missing recalculation)
+ CPPUNIT_ASSERT_EQUAL(OUString("102"), xCellA3->getString());
+ uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
+ // This was 8 (missing recalculation)
+ CPPUNIT_ASSERT_EQUAL(OUString("204"), xCellA4->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf157132)
+{
+ createSwDoc("tdf157132.odt");
+
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->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, ".uno:Copy", {});
+
+ // Go to A4 and paste
+ pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
+
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ 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("A2"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("2"), xCellA2->getString());
+ uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("3"), xCellA3->getString());
+ uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
+
+ // Without the fix in place, this test would have failed with
+ // - Expected: 6
+ // - Actual : 2
+ CPPUNIT_ASSERT_EQUAL(OUString("6"), xCellA4->getString());
+ uno::Reference<text::XTextRange> xCellA5(xTextTable->getCellByName("A5"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("7"), xCellA5->getString());
+
+ xTextTable.set(xTables->getByIndex(1), uno::UNO_QUERY);
+
+ xCellA2.set(xTextTable->getCellByName("A2"), 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(OUString("2"), xCellA2->getString());
+ xCellA3.set(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("3"), xCellA3->getString());
+ xCellA4.set(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("6"), xCellA4->getString());
+ xCellA5.set(xTextTable->getCellByName("A5"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("7"), xCellA5->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf147938)
+{
+ createSwDoc("tdf147938.fodt");
+
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
+ CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
+ 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(OUString("Bar\nbaz "),
+ pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+ 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(OUString("Bar\nbaz "),
+ pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
+
+ pWrtShell->Undo();
+
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
+ CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
+ pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
+
+ pWrtShell->Redo();
+
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
+ CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
+ pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
+
+ pWrtShell->Redo();
+
+ pWrtShell->Undo();
+
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
+ CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
+ pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
+
+ pWrtShell->Undo();
+
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
+ CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
+ 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");
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->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("D3"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("2.3"), xCellA1->getString());
+ uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName("D4"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("2345"), xCellA3->getString());
+ uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName("D5"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("23684.5"), 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");
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->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("A2"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("30"), 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 = pDoc->GetDocShell()->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, ".uno:ShowTrackedChanges", {});
+ 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(OUString("Row 2"), 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 = pDoc->GetDocShell()->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, ".uno:ShowTrackedChanges", {});
+ 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(OUString("Row 2"), rNode.GetTextNode()->GetText());
+
+ // delete the second table row
+ pWrtShell->DeleteRow();
+
+ // check cursor position (row 3)
+ SwNode& rNode2 = pWrtShell->GetCursor()->GetPoint()->GetNode();
+ CPPUNIT_ASSERT_EQUAL(OUString("Row 3"), rNode2.GetTextNode()->GetText());
+
+ // put cursor in the first row
+ pWrtShell->Up(/*bSelect=*/false, /*nCount=*/1);
+ SwNode& rNode3 = pWrtShell->GetCursor()->GetPoint()->GetNode();
+ CPPUNIT_ASSERT_EQUAL(OUString("12"), 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(OUString("Row 3"), rNode4.GetTextNode()->GetText());
+
+ // Check skipping previous lines
+
+ // restore deleted rows
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ SwNode& rNode5 = pWrtShell->GetCursor()->GetPoint()->GetNode();
+ CPPUNIT_ASSERT_EQUAL(OUString("Row 2"), rNode5.GetTextNode()->GetText());
+
+ // delete the second row
+ pWrtShell->DeleteRow();
+ SwNode& rNode7 = pWrtShell->GetCursor()->GetPoint()->GetNode();
+ CPPUNIT_ASSERT_EQUAL(OUString("Row 3"), 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(OUString("12"), rNode8.GetTextNode()->GetText());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132603)
+{
+ createSwDoc();
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+
+ uno::Sequence<beans::PropertyValue> aPropertyValues
+ = comphelper::InitPropertySequence({ { "Text", uno::Any(OUString("Comment")) } });
+
+ dispatchCommand(mxComponent, ".uno:InsertAnnotation", aPropertyValues);
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+
+ // Without the fix in place, it would crash here
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+
+ tools::JsonWriter aJsonWriter;
+ 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>("text"));
+ CPPUNIT_ASSERT_EQUAL("Comment"_ostr, aText);
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf117601)
+{
+ createSwDoc();
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+
+ uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
+ { { "Rows", uno::Any(sal_Int32(5)) }, { "Columns", uno::Any(sal_Int32(3)) } }));
+
+ dispatchCommand(mxComponent, ".uno:InsertTable", 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("B1"), uno::UNO_QUERY);
+ xCellB1->setString("test1");
+
+ uno::Reference<text::XTextRange> xCellB2(xTextTable->getCellByName("B2"), uno::UNO_QUERY);
+ xCellB2->setString("test2");
+
+ //go to middle row
+ pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_UP);
+ pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RIGHT);
+ Scheduler::ProcessEventsToIdle();
+
+ dispatchCommand(mxComponent, ".uno:EntireColumn", {});
+ dispatchCommand(mxComponent, ".uno:MergeCells", {});
+
+ 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, ".uno:Undo", {});
+
+ 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, ".uno:SetAnchorToPage", {});
+
+ //position has changed
+ CPPUNIT_ASSERT(aPos.X < xShape->getPosition().X);
+ CPPUNIT_ASSERT(aPos.Y < xShape->getPosition().Y);
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ 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, ".uno:SetAnchorToPage", {});
+
+ //position has changed
+ CPPUNIT_ASSERT(aPos.X < xShape->getPosition().X);
+ CPPUNIT_ASSERT(aPos.Y < xShape->getPosition().Y);
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ //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");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+
+ 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);
+
+ 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");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+
+ 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);
+
+ 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, ".uno:Undo", {});
+
+ 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");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+
+ 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);
+
+ 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, ".uno:Undo", {});
+
+ 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");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+
+ CPPUNIT_ASSERT_EQUAL(1, getShapes());
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+
+ dispatchCommand(mxComponent, ".uno:Cut", {});
+
+ CPPUNIT_ASSERT_EQUAL(0, getShapes());
+
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ CPPUNIT_ASSERT_EQUAL(1, getShapes());
+
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ 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);
+
+ 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, ".uno:Undo", {});
+
+ // 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, ".uno:Undo", {});
+
+ 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, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(1, getShapes());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(0, getShapes());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(1, getShapes());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132637_protectTrackChanges)
+{
+ createSwDoc("tdf132637_protectTrackChanges.doc");
+ SwDoc* pDoc = getSwDoc();
+
+ // The password should only prevent turning off track changes, not open as read-only
+ CPPUNIT_ASSERT(!pDoc->GetDocShell()->IsReadOnly());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf127652)
+{
+ createSwDoc("tdf127652.odt");
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* const pWrtShell = pDoc->GetDocShell()->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());
+ 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(
+ "AnchorType", 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, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:Cut", {});
+
+ CPPUNIT_ASSERT_EQUAL(0, getShapes());
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ 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(mxComponentContext);
+ 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(OUString("BMP")) } }));
+ 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 = pDoc->GetDocShell()->GetWrtShell();
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+
+ 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);
+
+ 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("A1"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(Color(0x009353), getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A2"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A5"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A6"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(Color(0xbee3d3), getProperty<Color>(xCell, "BackColor"));
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:Cut", {});
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount());
+
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ 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, ".uno:GoUp", {});
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ 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, ".uno:Undo", {});
+ }
+
+ 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, ".uno:Redo", {});
+ }
+
+ 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("A1"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(Color(0x009353), getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A2"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A5"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A6"), 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, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A7"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A8"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, "BackColor"));
+
+ xCell.set(xTextTable->getCellByName("A9"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(Color(0xbee3d3), getProperty<Color>(xCell, "BackColor"));
+}
+
+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("A1"), 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, "CharWeight"));
+
+ xCell.set(xTextTable->getCellByName("A2"), 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, "CharWeight"));
+
+ xCell.set(xTextTable->getCellByName("A3"), 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, "CharWeight"));
+
+ xCell.set(xTextTable->getCellByName("A4"), 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, "CharWeight"));
+
+ dispatchCommand(mxComponent, ".uno:GoDown", {});
+ dispatchCommand(mxComponent, ".uno:GoDown", {});
+ dispatchCommand(mxComponent, ".uno:LineDownSel", {});
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());
+
+ xCell.set(xTextTable->getCellByName("A1"), 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, "CharWeight"));
+
+ xCell.set(xTextTable->getCellByName("A2"), 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, "CharWeight"));
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());
+
+ xCell.set(xTextTable->getCellByName("A1"), 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, "CharWeight"));
+
+ xCell.set(xTextTable->getCellByName("A2"), 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, "CharWeight"));
+
+ xCell.set(xTextTable->getCellByName("A3"), 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, "CharWeight"));
+
+ xCell.set(xTextTable->getCellByName("A4"), 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, "CharWeight"));
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf138897)
+{
+ createSwDoc("tdf100018-1.odt");
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:Cut", {});
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+ // this was crashing
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ dispatchCommand(mxComponent, ".uno:Redo", {});
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ dispatchCommand(mxComponent, ".uno:Redo", {});
+}
+
+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("com.sun.star.text.Defaults"), css::uno::UNO_QUERY_THROW);
+ const css::uno::Any aOrig = xTextDefaults->getPropertyValue("TabStopDistance");
+ 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("Foo");
+
+ CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
+ CPPUNIT_ASSERT_EQUAL(OUString("Foo"), xParagraph->getString());
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+ dispatchCommand(mxComponent, ".uno:GoToEndOfDoc", {});
+
+ const css::uno::Any aNew(nDefTab * 2);
+ xTextDefaults->setPropertyValue("TabStopDistance", aNew);
+ // it may become slightly different because of conversions, so get the actual value
+ const css::uno::Any aNewCorrected = xTextDefaults->getPropertyValue("TabStopDistance");
+ 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, ".uno:ClipboardFormatItems", aPropertyValues);
+
+ CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
+ CPPUNIT_ASSERT_EQUAL(OUString("FooFoo"), 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("TabStopDistance"));
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf128106)
+{
+ createSwDoc("cross_reference_demo_bmk.odt");
+
+ const auto aPropertyValues
+ = comphelper::InitPropertySequence({ { "FileName", css::uno::Any(maTempFile.GetURL()) } });
+ dispatchCommand(mxComponent, ".uno:NewGlobalDoc", aPropertyValues);
+
+ mxComponent = loadFromDesktop(maTempFile.GetURL());
+
+ SwWrtShell* pWrtShell = getSwDoc()->GetDocShell()->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(false, false,
+ nullptr);
+ // note: this has called SwGetRefFieldType::UpdateGetReferences()
+ SwFieldType const* const 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 const* const pA, auto const* const pB) {
+ SwTextField const* const pHintA(pA->GetTextField());
+ SwTextField const* const 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(OUString("bookmarkchapter1_text"),
+ static_cast<SwGetRefField const*>(fields[0]->GetField())->GetSetRefName());
+ CPPUNIT_ASSERT_EQUAL(OUString("Text"), static_cast<SwGetRefField const*>(fields[0]->GetField())
+ ->GetExpandedTextOfReferencedTextNode(
+ *pWrtShell->GetLayout(), nullptr, nullptr));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[1]->GetField()->GetSubType());
+ CPPUNIT_ASSERT(
+ static_cast<SwGetRefField const*>(fields[1]->GetField())->IsRefToHeadingCrossRefBookmark());
+ CPPUNIT_ASSERT_EQUAL(OUString("Chapter 2"),
+ static_cast<SwGetRefField const*>(fields[1]->GetField())->GetPar2());
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[2]->GetField()->GetSubType());
+ CPPUNIT_ASSERT_EQUAL(OUString("Bookmarkchapter1"),
+ static_cast<SwGetRefField const*>(fields[2]->GetField())->GetSetRefName());
+ CPPUNIT_ASSERT_EQUAL(OUString("Chapter 1"),
+ static_cast<SwGetRefField const*>(fields[2]->GetField())->GetPar2());
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[3]->GetField()->GetSubType());
+ CPPUNIT_ASSERT_EQUAL(OUString("bookmarkchapter1_text"),
+ static_cast<SwGetRefField const*>(fields[3]->GetField())->GetSetRefName());
+ CPPUNIT_ASSERT_EQUAL(OUString("Text"),
+ 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(OUString("Chapter 1.1"),
+ 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(OUString("Chapter 2"),
+ static_cast<SwGetRefField const*>(fields[5]->GetField())->GetPar2());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf103612)
+{
+ createSwGlobalDoc("DUMMY.odm");
+ SwDoc* pGlobalDoc = getSwDoc();
+ CPPUNIT_ASSERT_EQUAL(
+ size_t(1),
+ pGlobalDoc->getIDocumentLinksAdministration().GetLinkManager().GetLinks().size());
+ pGlobalDoc->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks(false, false,
+ nullptr);
+
+ xmlDocUniquePtr pLayout = parseLayoutDump();
+
+ assertXPath(pLayout, "/root/page[1]/body/section[1]/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "portion"_ostr, "Text before section");
+ // the inner section and its content was hidden
+ assertXPath(pLayout, "/root/page[1]/body/section[2]/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "portion"_ostr, "Text inside section before ToC");
+ assertXPath(pLayout, "/root/page[1]/body/section[3]/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "portion"_ostr, "Table of Contents");
+ assertXPath(pLayout, "/root/page[1]/body/section[4]/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "portion"_ostr, "First header*1");
+ assertXPath(pLayout, "/root/page[1]/body/section[4]/txt[2]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "portion"_ostr, "Second header*1");
+ assertXPath(pLayout, "/root/page[1]/body/section[5]/txt[2]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "portion"_ostr, "Text inside section after ToC");
+ assertXPath(pLayout, "/root/page[1]/body/section[6]/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr,
+ "portion"_ostr, "Text after section");
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf97899)
+{
+ createSwDoc();
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ SwPaM* pCursor = pDoc->GetEditShell()->GetCursor();
+ IDocumentContentOperations& rIDCO(pDoc->getIDocumentContentOperations());
+
+ // Create an Ordered List
+ rIDCO.InsertString(*pCursor, "\ta");
+ pWrtShell->SplitNode();
+ rIDCO.InsertString(*pCursor, " b");
+ pWrtShell->SplitNode();
+ rIDCO.InsertString(*pCursor, " \t c");
+
+ dispatchCommand(mxComponent, ".uno:SelectAll", {});
+ dispatchCommand(mxComponent, ".uno:DefaultNumbering", {});
+
+ // tdf#109285: RemoveLeadingWhiteSpace from all numbered paragraphs
+ getParagraph(1, "a");
+ getParagraph(2, "b");
+ getParagraph(3, "c");
+
+ // Save it as DOCX & load it again
+ saveAndReload("Office Open XML Text");
+ uno::Reference<container::XIndexAccess> xNumberingRules
+ = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1), "NumberingRules");
+ 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, ".uno:UpdateAllIndexes", {});
+
+ 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"_ostr, 2);
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf151462)
+{
+ createSwDoc("tdf151462.odt");
+ dispatchCommand(mxComponent, ".uno:UpdateAllIndexes", {});
+
+ 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]"_ostr,
+ "portion"_ostr, "sub one");
+ assertXPath(pLayout,
+ "/root/page[1]/body/txt[2]/anchored/fly/section/txt[2]/SwParaPortion/"
+ "SwLineLayout[1]/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "sub two");
+ assertXPath(pLayout,
+ "/root/page[1]/body/txt[2]/anchored/fly/section/txt[3]/SwParaPortion/"
+ "SwLineLayout[1]/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "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]"_ostr,
+ "portion"_ostr, "another sub one");
+ assertXPath(pLayout,
+ "/root/page[1]/body/txt[6]/anchored/fly/section/txt[2]/SwParaPortion/"
+ "SwLineLayout[1]/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "another sub two");
+ assertXPath(pLayout,
+ "/root/page[1]/body/txt[6]/anchored/fly/section/txt[3]/SwParaPortion/"
+ "SwLineLayout[1]/SwLinePortion[1]"_ostr,
+ "portion"_ostr, "another sub three");
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf151801)
+{
+ Resetter resetter([]() {
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::AutoCorrect::SingleQuoteAtStart::set(0, pBatch);
+ officecfg::Office::Common::AutoCorrect::SingleQuoteAtEnd::set(0, pBatch);
+ return pBatch->commit();
+ });
+ // Set Single Quotes › and ‹
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::AutoCorrect::SingleQuoteAtStart::set(8250, pBatch);
+ officecfg::Office::Common::AutoCorrect::SingleQuoteAtEnd::set(8249, pBatch);
+ pBatch->commit();
+
+ createSwDoc("tdf151801.fodt");
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ // Single starting quote: 'word -> ›word
+ emulateTyping(*pTextDoc, u"'word");
+ OUString sReplaced(u"\u203Aword"_ustr);
+ CPPUNIT_ASSERT_EQUAL(sReplaced, getParagraph(1)->getString());
+ // Single ending quote: ›word' -> ›word‹
+ emulateTyping(*pTextDoc, u"'");
+ sReplaced += u"\u2039";
+ CPPUNIT_ASSERT_EQUAL(sReplaced, getParagraph(1)->getString());
+ // Use apostrophe without preceding starting quote: word' -> word’
+ emulateTyping(*pTextDoc, u" word'");
+ sReplaced += u" word\u2019";
+ CPPUNIT_ASSERT_EQUAL(sReplaced, getParagraph(1)->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testCursorPositionAfterUndo)
+{
+ createSwDoc("cursor_position_after_undo.odt");
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+ // switch on "Outline Folding" mode
+ dispatchCommand(mxComponent, ".uno:ShowOutlineContentVisibilityButton", {});
+ 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, ".uno:SelectWord", {});
+
+ // check the word is select
+ SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
+ CPPUNIT_ASSERT_EQUAL(OUString("tincidunt"), pShellCursor->GetText());
+
+ // remember the cursor position for comparison
+ SwPosition aCursorPos(*pWrtShell->GetCursor()->GetPoint());
+
+ // delete the selected word
+ pWrtShell->Delete();
+
+ // undo delete
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ // 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, ".uno:ShowOutlineContentVisibilityButton", {});
+ 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");
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Right Page"), pWrtShell->GetCurPageStyle());
+
+ dispatchCommand(mxComponent, ".uno:ResetAttributes", {}); // Ctrl+M "Clear Direct Formatting"
+ // Make sure that clearing direct formatting doesn't clear the page style
+ CPPUNIT_ASSERT_EQUAL(OUString("Right Page"), pWrtShell->GetCurPageStyle());
+
+ // Make sure that the page break with page style survives ODF save-and-reload
+ saveAndReload("writer8");
+
+ xmlDocUniquePtr pXml = parseExport("content.xml");
+ CPPUNIT_ASSERT(pXml);
+ OUString para_style_name = getXPath(
+ pXml, "/office:document-content/office:body/office:text/text:p"_ostr, "style-name"_ostr);
+ // 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"_ostr, "paragraph");
+ // Without the fix in place, the autostyle had no parent
+ assertXPath(pXml, para_style_path, "parent-style-name"_ostr, "Standard");
+ assertXPath(pXml, para_style_path, "master-page-name"_ostr, "Right_20_Page");
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf62032ApplyStyle)
+{
+ createSwDoc("tdf62032_apply_style.odt");
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtSh = pDoc->GetDocShell()->GetWrtShell();
+
+ pWrtSh->Down(/*bSelect=*/false);
+
+ uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence({
+ { "Style", uno::Any(OUString("A 2")) },
+ { "FamilyName", uno::Any(OUString("ParagraphStyles")) },
+ });
+ dispatchCommand(mxComponent, ".uno:StyleApply", aPropertyValues);
+
+ // Without the fix in place, it fails with:
+ // - Expected: 1.1
+ // - Actual : 2
+ CPPUNIT_ASSERT_EQUAL(OUString("1.1"),
+ getProperty<OUString>(getParagraph(2), "ListLabelString").trim());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf156560)
+{
+ createSwDoc("tdf156560.docx");
+
+ uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, "HeaderIsOn"));
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ 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, ".uno:InsertHeader", {});
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf158459)
+{
+ createSwDoc("tdf158459_tracked_changes_across_nodes.fodt");
+ SwDoc* pDoc = getSwDoc();
+
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->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 = rNodes.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(OUString("abdf"), pTextNode->GetText());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf158703)
+{
+ // Given a document with French text, consisting of a word and several spaces:
+ createSwDoc("tdf158703.fodt");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+
+ dispatchCommand(mxComponent, ".uno:GoToEndOfDoc", {});
+
+ // Typing ":" after the spaces should start auto-correction, which is expected to
+ // remove the spaces, and insert an NBSP instead. It must not crash.
+ emulateTyping(*pTextDoc, u":");
+ CPPUNIT_ASSERT_EQUAL(u"Foo\u00A0:"_ustr, getParagraph(1)->getString());
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */