From 1f6918b458e5edee8daa7c81675b30d50533249f Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 30 Aug 2022 12:00:32 +0200 Subject: [PATCH] Split CppunitTest_sw_uiwriter3 into a uiwriter3 and a uiwriter8 My build with 16G ram now regularly fails with: g++: internal compiler error: Killed (program cc1plus) Please submit a full bug report, with preprocessed source if appropriate. See for instructions. make[1]: *** [solenv/gbuild/LinkTarget.mk:337: workdir/CxxObject/sw/qa/extras/uiwriter/uiwriter3.o] Error 4 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:289: build] Error 2 Change-Id: Ia758f2e905a13369a9eef7eece4104bb9ea76303 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139025 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- sw/CppunitTest_sw_uiwriter8.mk | 14 + sw/Module_sw.mk | 1 + sw/qa/extras/uiwriter/uiwriter3.cxx | 2335 +------------------------- sw/qa/extras/uiwriter/uiwriter8.cxx | 2371 +++++++++++++++++++++++++++ 4 files changed, 2387 insertions(+), 2334 deletions(-) create mode 100644 sw/CppunitTest_sw_uiwriter8.mk create mode 100644 sw/qa/extras/uiwriter/uiwriter8.cxx diff --git a/sw/CppunitTest_sw_uiwriter8.mk b/sw/CppunitTest_sw_uiwriter8.mk new file mode 100644 index 000000000000..a802c0caa180 --- /dev/null +++ b/sw/CppunitTest_sw_uiwriter8.mk @@ -0,0 +1,14 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#************************************************************************* + +$(eval $(call sw_uiwriter_test,8)) + +# vim: set noet sw=4 ts=4: diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk index e93ae26ceb42..a784af17d121 100644 --- a/sw/Module_sw.mk +++ b/sw/Module_sw.mk @@ -116,6 +116,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\ CppunitTest_sw_uiwriter5 \ CppunitTest_sw_uiwriter6 \ CppunitTest_sw_uiwriter7 \ + CppunitTest_sw_uiwriter8 \ CppunitTest_sw_layoutwriter \ CppunitTest_sw_layoutwriter2 \ CppunitTest_sw_mailmerge \ diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx index 062fb0acc195..ab028d9da5ce 100644 --- a/sw/qa/extras/uiwriter/uiwriter3.cxx +++ b/sw/qa/extras/uiwriter/uiwriter3.cxx @@ -9,12 +9,7 @@ #include #include -#include #include -#include -#include -#include -#include #include #include #include @@ -22,27 +17,17 @@ #include #include #include -#include -#include #include -#include -#include -#include #include #include #include #include -#include -#include -#include #include -#include #include #include -#include #include -#include +#include namespace { @@ -2302,2324 +2287,6 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf130680) CPPUNIT_ASSERT_EQUAL(sal_Int32(23), xIndexAccess->getCount()); } -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf131684) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf131684.docx"); - SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); - - uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference 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", {}); - - rtl::Reference xTransfer = new SwTransferable(*pWrtShell); - xTransfer->Cut(); - Scheduler::ProcessEventsToIdle(); - CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount()); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); - - TransferableDataHelper aHelper(xTransfer); - SwTransferable::Paste(*pWrtShell, aHelper); - 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]", "id"); - OUString const sectionLower = getXPath(pXmlDoc, "/root/page[1]/body/section[7]", "lower"); - OUString const textId = getXPath(pXmlDoc, "/root/page[1]/body/section[7]/txt[1]", "id"); - OUString const textUpper = getXPath(pXmlDoc, "/root/page[1]/body/section[7]/txt[1]", "upper"); - CPPUNIT_ASSERT_EQUAL(textId, sectionLower); - CPPUNIT_ASSERT_EQUAL(sectionId, textUpper); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf132420) -{ - createSwDoc(DATA_DIRECTORY, "tdf132420.odt"); - - CPPUNIT_ASSERT_EQUAL(12, getShapes()); - - dispatchCommand(mxComponent, ".uno:SelectAll", {}); - Scheduler::ProcessEventsToIdle(); - - dispatchCommand(mxComponent, ".uno:Cut", {}); - Scheduler::ProcessEventsToIdle(); - CPPUNIT_ASSERT_EQUAL(0, getShapes()); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - Scheduler::ProcessEventsToIdle(); - - //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(SwUiWriterTest3, testTdf132744) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf132744.odt"); - SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); - - // 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", {}); - Scheduler::ProcessEventsToIdle(); - - rtl::Reference xTransfer = new SwTransferable(*pWrtShell); - xTransfer->Cut(); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(0, getShapes()); - - TransferableDataHelper aHelper(xTransfer); - SwTransferable::Paste(*pWrtShell, aHelper); - Scheduler::ProcessEventsToIdle(); - - //Without the fix in place, the image wouldn't be pasted - CPPUNIT_ASSERT_EQUAL(1, getShapes()); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf146622) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "TC-table-del-add.docx"); - CPPUNIT_ASSERT(pDoc); - SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); - CPPUNIT_ASSERT(pWrtShell); - - CPPUNIT_ASSERT_MESSAGE("redlining should be on", - pDoc->getIDocumentRedlineAccess().IsRedlineOn()); - - uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xTables(xTablesSupplier->getTextTables(), - uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTables->getCount()); - uno::Reference xTableNames = xTablesSupplier->getTextTables(); - CPPUNIT_ASSERT(xTableNames->hasByName("Table1")); - uno::Reference 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", {}); - Scheduler::ProcessEventsToIdle(); - - dispatchCommand(mxComponent, ".uno:DeleteRows", {}); - CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount()); - - dispatchCommand(mxComponent, ".uno:SelectAll", {}); - dispatchCommand(mxComponent, ".uno:SelectAll", {}); - Scheduler::ProcessEventsToIdle(); - - 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(SwUiWriterTest3, testTdf146962) -{ - // load a 2-row table, set Hide Changes mode and delete the first row with change tracking - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); - 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", 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", 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", 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", 2); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf147347) -{ - // load a 2-row table, set Hide Changes mode and delete the table with change tracking - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); - 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", 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", 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", 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", 2); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf148345) -{ - // load a 2-row table, set Hide Changes mode and delete the first row with change tracking - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); - 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", 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", 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", 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", 2); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, 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 - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); - 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", {}); - Scheduler::ProcessEventsToIdle(); - - xmlDocUniquePtr pXmlDoc = parseLayoutDump(); - // 3-row, overwriting cells of the second row and inserting a new row - // with the 2-row clipboard table content - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 3); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/Text", "Portion", "hello"); - - // Undo - - dispatchCommand(mxComponent, ".uno:Undo", {}); - discardDumpedLayout(); - pXmlDoc = parseLayoutDump(); - // 2 rows again, no copied text content - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/Text", 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", 2); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt", 2); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/Text", "Portion", - "Some text..."); - // the empty paragraph in A2 - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[2]/Text", 0); - - // insert the table, as a nested one in cell "A2" - dispatchCommand(mxComponent, ".uno:Paste", {}); - Scheduler::ProcessEventsToIdle(); - discardDumpedLayout(); - pXmlDoc = parseLayoutDump(); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab", 1); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab/row", 2); - - // Undo - - dispatchCommand(mxComponent, ".uno:Undo", {}); - Scheduler::ProcessEventsToIdle(); - discardDumpedLayout(); - pXmlDoc = parseLayoutDump(); - // 2 rows again, no copied text content - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/Text", "Portion", - "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", {}); - Scheduler::ProcessEventsToIdle(); - - 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", 3); - // This was "Some text..." with a nested table - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/Text", "Portion", "hello"); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf148791) -{ - // test Paste as Rows Above with centered table alignment - - // load a 2-row table - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); - 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", {}); - Scheduler::ProcessEventsToIdle(); - - xmlDocUniquePtr pXmlDoc = parseLayoutDump(); - // Paste as Rows Above results 4-row table with default table alignment - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 4); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[1]/cell[1]/txt/Text", "Portion", "hello"); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[3]/cell[1]/txt/Text", "Portion", "hello"); - - // set table alignment to center, select and copy the table again - uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), - uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); - - uno::Reference xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY); - - // Default table alignment - CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::FULL, - getProperty(xTextTable, "HoriOrient")); - - //CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xTextTable, "TableTemplateName")); - uno::Reference xTableProps(xTextTable, uno::UNO_QUERY_THROW); - - xTableProps->setPropertyValue("HoriOrient", uno::Any(text::HoriOrientation::CENTER)); - - CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, - getProperty(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", {}); - Scheduler::ProcessEventsToIdle(); - - 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", 8); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[1]/cell[1]/txt/Text", "Portion", "hello"); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[3]/cell[1]/txt/Text", "Portion", "hello"); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[5]/cell[1]/txt/Text", "Portion", "hello"); - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[7]/cell[1]/txt/Text", "Portion", "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", {}); - Scheduler::ProcessEventsToIdle(); - - 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", 16); - // there are two nested tables after the paste - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab", 2); - - // tdf#64902 add a test case for repeated table headings - - xTableProps->setPropertyValue("RepeatHeadline", uno::Any(true)); - CPPUNIT_ASSERT(getProperty(xTextTable, "RepeatHeadline")); - - xTableProps->setPropertyValue("HeaderRowCount", uno::Any(sal_Int32(3))); - CPPUNIT_ASSERT_EQUAL(sal_Int32(3), getProperty(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", {}); - Scheduler::ProcessEventsToIdle(); - - discardDumpedLayout(); - pXmlDoc = parseLayoutDump(); - // repeating table header (and its thead/tbody indentation) doesn't effect row number - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 32); - // there are two nested tables after the paste - assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab", 4); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf135014) -{ - createSwDoc(); - - uno::Sequence aArgs( - comphelper::InitPropertySequence({ { "KeyModifier", uno::Any(sal_Int32(0)) } })); - - // Toggle Numbering List - dispatchCommand(mxComponent, ".uno:DefaultBullet", aArgs); - Scheduler::ProcessEventsToIdle(); - - uno::Sequence aArgs2(comphelper::InitPropertySequence( - { { "Param", uno::Any(OUString("NewNumberingStyle")) }, - { "Family", uno::Any(static_cast(SfxStyleFamily::Pseudo)) } })); - - // New Style from selection - dispatchCommand(mxComponent, ".uno:StyleNewByExample", aArgs2); - Scheduler::ProcessEventsToIdle(); - - // Without the fix in place, this test would have failed here - reload("Office Open XML Text", "tdf135014.docx"); - - xmlDocUniquePtr pXmlStyles = parseExport("word/styles.xml"); - assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='NewNumberingStyle']/w:qFormat", 1); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf130629) -{ - createSwDoc(); - SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); - - uno::Sequence aArgs( - comphelper::InitPropertySequence({ { "KeyModifier", uno::Any(KEY_MOD1) } })); - - dispatchCommand(mxComponent, ".uno:BasicShapes.diamond", aArgs); - Scheduler::ProcessEventsToIdle(); - - 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); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(1, getShapes()); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf145584) -{ - std::shared_ptr pPDFium = vcl::pdf::PDFiumLibrary::get(); - if (!pPDFium) - { - return; - } - SwDoc* const pDoc = createSwDoc(); - 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 aFilterData( - comphelper::InitPropertySequence({ { "Selection", uno::Any(true) } })); - - uno::Sequence 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); - - // Parse the export result. - SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ); - SvMemoryStream aMemory; - aMemory.WriteStream(aFile); - std::unique_ptr pPdfDocument - = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize(), OString()); - CPPUNIT_ASSERT(pPdfDocument); - CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount()); - std::unique_ptr pPdfPage = pPdfDocument->openPage(/*nIndex=*/0); - CPPUNIT_ASSERT(pPdfPage); - CPPUNIT_ASSERT_EQUAL(1, pPdfPage->getObjectCount()); - std::unique_ptr pPdfTextPage = pPdfPage->getTextPage(); - CPPUNIT_ASSERT(pPdfTextPage); - - std::unique_ptr pPageObject = pPdfPage->getObject(0); - OUString sText = pPageObject->getText(pPdfTextPage); - CPPUNIT_ASSERT_EQUAL(OUString("World"), sText); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf140731) -{ - SwDoc* const pDoc = createSwDoc(); - SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell(); - CPPUNIT_ASSERT(pWrtSh); - - pWrtSh->Insert("Lorem"); - - SwXTextDocument* pTextDoc = dynamic_cast(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", {}); - Scheduler::ProcessEventsToIdle(); - - dispatchCommand(mxComponent, ".uno:Copy", {}); - Scheduler::ProcessEventsToIdle(); - - dispatchCommand(mxComponent, ".uno:Paste", {}); - Scheduler::ProcessEventsToIdle(); - - dispatchCommand(mxComponent, ".uno:Paste", {}); - Scheduler::ProcessEventsToIdle(); - } - - dispatchCommand(mxComponent, ".uno:GoToStartOfDoc", {}); - Scheduler::ProcessEventsToIdle(); - - // Format->Text operations on small selections (which would generate <~500 redlines) - // changetracking still working - dispatchCommand(mxComponent, ".uno:TrackChanges", {}); - Scheduler::ProcessEventsToIdle(); - - SwCursorShell* pShell(pDoc->GetEditShell()); - - pShell->SelectTextModel(1, 500); - - dispatchCommand(mxComponent, ".uno:ChangeCaseToTitleCase", {}); - Scheduler::ProcessEventsToIdle(); - - SwEditShell* const pEditShell(pDoc->GetEditShell()); - CPPUNIT_ASSERT_EQUAL(static_cast(120), - pEditShell->GetRedlineCount()); - - //Removing all the redlines. - dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(static_cast(0), pEditShell->GetRedlineCount()); - - dispatchCommand(mxComponent, ".uno:SelectAll", {}); - Scheduler::ProcessEventsToIdle(); - - dispatchCommand(mxComponent, ".uno:ChangeCaseToTitleCase", {}); - Scheduler::ProcessEventsToIdle(); - - // Without the fix in place, on big selections writer would freeze. Now it ignores change tracking. - CPPUNIT_ASSERT_EQUAL(static_cast(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", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("LOREM IPSUM DOLOR SIT AMET")); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf116315) -{ - SwDoc* const pDoc = createSwDoc(); - 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(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(SwUiWriterTest3, testTdf144364) -{ - SwDoc* const pDoc = createSwDoc(); - SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell(); - CPPUNIT_ASSERT(pWrtSh); - - // expands autotext (via F3) - pWrtSh->Insert("AR"); - - SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); - pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F3); - Scheduler::ProcessEventsToIdle(); - - // was ...'letter of ' - CPPUNIT_ASSERT_EQUAL( - OUString("We hereby acknowledge the receipt of your letter of ."), - getParagraph(1)->getString()); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf141613) -{ - SwDoc* const pDoc = createSwDoc(); - 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 xPageStyle(getStyles("PageStyles")->getByName("Standard"), - uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(true, getProperty(xPageStyle, "HeaderIsOn")); - CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(1)->getString()); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - - CPPUNIT_ASSERT_EQUAL(false, getProperty(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(SwUiWriterTest3, testTdf107494) -{ - createSwDoc(); - - // Create a graphic object, but don't insert it yet. - uno::Reference xFactory(mxComponent, uno::UNO_QUERY); - uno::Reference xTextGraphic( - xFactory->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY); - - uno::Reference xTextContent(xTextGraphic, uno::UNO_QUERY); - - uno::Reference xPageStyle(getStyles("PageStyles")->getByName("Standard"), - uno::UNO_QUERY); - - xPageStyle->setPropertyValue("HeaderIsOn", uno::Any(true)); - - uno::Reference xHeader( - getProperty>(xPageStyle, "HeaderText")); - CPPUNIT_ASSERT(xHeader.is()); - uno::Reference 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 xFooter( - getProperty>(xPageStyle, "FooterText")); - CPPUNIT_ASSERT(xFooter.is()); - uno::Reference 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(SwUiWriterTest3, testTdf133358) -{ - SwDoc* const pDoc = createSwDoc(); - SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell(); - CPPUNIT_ASSERT(pWrtSh); - - pWrtSh->Insert("Test"); - - CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(1)->getString()); - - uno::Reference xParagraph(getParagraph(1), uno::UNO_QUERY); - - CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty(xParagraph, "ParaLeftMargin")); - - dispatchCommand(mxComponent, ".uno:IncrementIndent", {}); - - CPPUNIT_ASSERT_EQUAL(sal_Int32(1251), getProperty(xParagraph, "ParaLeftMargin")); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - - CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty(xParagraph, "ParaLeftMargin")); - - // Without the fix in place, this test would have crashed here - dispatchCommand(mxComponent, ".uno:Redo", {}); - - CPPUNIT_ASSERT_EQUAL(sal_Int32(1251), getProperty(xParagraph, "ParaLeftMargin")); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf131771) -{ - createSwDoc(); - - uno::Sequence aArgs(comphelper::InitPropertySequence( - { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } })); - - dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); - Scheduler::ProcessEventsToIdle(); - - uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), - uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); - - uno::Reference xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY); - - CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xTextTable, "TableTemplateName")); - uno::Reference xTableProps(xTextTable, uno::UNO_QUERY_THROW); - xTableProps->setPropertyValue("TableTemplateName", uno::Any(OUString("Default Style"))); - - CPPUNIT_ASSERT_EQUAL(OUString("Default Style"), - getProperty(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(xTextTable, "TableTemplateName")); - - uno::Reference 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(xTextTable2, "TableTemplateName")); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf80663) -{ - createSwDoc(); - - uno::Sequence aArgs(comphelper::InitPropertySequence( - { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } })); - - dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); - Scheduler::ProcessEventsToIdle(); - - uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), - uno::UNO_QUERY); - uno::Reference 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", {}); - Scheduler::ProcessEventsToIdle(); - - 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", {}); - Scheduler::ProcessEventsToIdle(); - - 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(SwUiWriterTest3, testTdf130805) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf130805.odt"); - - const SwFrameFormats& 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); - - auto pTxAnch = pTxBxFrm->GetAnchor().GetContentAnchor(); - auto pShpAnch = pShape->GetAnchor().GetContentAnchor(); - CPPUNIT_ASSERT(pTxAnch); - CPPUNIT_ASSERT(pShpAnch); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("The textbox got apart!", pTxAnch->nNode, pShpAnch->nNode); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf107893) -{ - //Open the sample doc - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf107893.odt"); - - //Get the format of the shape - const SwFrameFormats& rFrmFormats = *pDoc->GetSpzFrameFormats(); - CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1))); - SwFrameFormat* 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(SwUiWriterTest3, testTdf121031) -{ - createSwDoc(); - - uno::Sequence aArgs(comphelper::InitPropertySequence( - { { "Rows", uno::Any(sal_Int32(3)) }, { "Columns", uno::Any(sal_Int32(3)) } })); - - dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); - Scheduler::ProcessEventsToIdle(); - - uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), - uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); - - dispatchCommand(mxComponent, ".uno:DeleteTable", {}); - Scheduler::ProcessEventsToIdle(); - CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount()); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - Scheduler::ProcessEventsToIdle(); - CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); - - // Without the fix in place, the table would be hidden - xmlDocUniquePtr pXmlDoc = parseLayoutDump(); - assertXPath(pXmlDoc, "/root/page[1]/body/tab", 1); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, TestTextBoxCrashAfterLineDel) -{ - // Open the desired file - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "txbx_crash.odt"); - - // Get the format of the shape - const SwFrameFormats& rFrmFormats = *pDoc->GetSpzFrameFormats(); - CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1))); - SwFrameFormat* 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(SwUiWriterTest3, testTdf121546) -{ - createSwDoc(DATA_DIRECTORY, "tdf121546.odt"); - - CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString()); - - dispatchCommand(mxComponent, ".uno:SelectAll", {}); - Scheduler::ProcessEventsToIdle(); - - dispatchCommand(mxComponent, ".uno:Cut", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(1, getParagraphs()); - - // Create a new document - createSwDoc(); - - dispatchCommand(mxComponent, ".uno:Paste", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString()); - - dispatchCommand(mxComponent, ".uno:SelectAll", {}); - Scheduler::ProcessEventsToIdle(); - - dispatchCommand(mxComponent, ".uno:Cut", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(1, getParagraphs()); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString()); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - Scheduler::ProcessEventsToIdle(); - - SwXTextDocument* pTextDoc = dynamic_cast(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(SwUiWriterTest3, testTdf145621) -{ - createSwDoc(DATA_DIRECTORY, "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(SwUiWriterTest3, testTdf134626) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf134626.odt"); - SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); - - CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString()); - - dispatchCommand(mxComponent, ".uno:SelectAll", {}); - - rtl::Reference xTransfer = new SwTransferable(*pWrtShell); - xTransfer->Copy(); - Scheduler::ProcessEventsToIdle(); - TransferableDataHelper aHelper(xTransfer); - - // Create a new document - pDoc = createSwDoc(); - 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) - { - SwTransferable::Paste(*pWrtShell, aHelper); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString()); - - SwTransferable::Paste(*pWrtShell, aHelper); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(OUString("AppleApple"), getParagraph(1)->getString()); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString()); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(OUString(""), getParagraph(1)->getString()); - } -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf139566) -{ - SwDoc* pDoc = createSwDoc(); - SwWrtShell* pWrtSh = pDoc->GetDocShell()->GetWrtShell(); - - uno::Sequence aArgs(comphelper::InitPropertySequence( - { { "Rows", uno::Any(sal_Int32(1)) }, { "Columns", uno::Any(sal_Int32(1)) } })); - - dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); - Scheduler::ProcessEventsToIdle(); - - // 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", {}); - Scheduler::ProcessEventsToIdle(); - - uno::Reference xFrames = mxDesktop->getFrames(); - sal_Int32 nFrames = xFrames->getCount(); - - // Create a second window so the first window looses focus - dispatchCommand(mxComponent, ".uno:NewWindow", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(nFrames + 1, xFrames->getCount()); - - dispatchCommand(mxComponent, ".uno:CloseWin", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(nFrames, xFrames->getCount()); - - uno::Reference xModel(mxComponent, uno::UNO_QUERY); - uno::Reference xSelections(xModel->getCurrentSelection(), - uno::UNO_QUERY); - - // Without the fix in place, this test would have failed here - CPPUNIT_ASSERT(xSelections.is()); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf96067) -{ - createSwDoc(); - - uno::Sequence aArgs(comphelper::InitPropertySequence( - { { "Rows", uno::Any(sal_Int32(3)) }, { "Columns", uno::Any(sal_Int32(3)) } })); - - dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); - Scheduler::ProcessEventsToIdle(); - - uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), - uno::UNO_QUERY); - uno::Reference 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", {}); - Scheduler::ProcessEventsToIdle(); - - 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", {}); - Scheduler::ProcessEventsToIdle(); - - 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(SwUiWriterTest3, testTdf87199) -{ - createSwDoc(); - - uno::Sequence aArgs(comphelper::InitPropertySequence( - { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(1)) } })); - - dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); - - uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), - uno::UNO_QUERY); - uno::Reference 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 xCellA1(xTextTable->getCellByName("A1"), uno::UNO_QUERY); - xCellA1->setString("test1"); - - uno::Reference xCellA2(xTextTable->getCellByName("A2"), uno::UNO_QUERY); - xCellA2->setString("test2"); - - dispatchCommand(mxComponent, ".uno:EntireColumn", {}); - dispatchCommand(mxComponent, ".uno:MergeCells", {}); - Scheduler::ProcessEventsToIdle(); - - 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", {}); - Scheduler::ProcessEventsToIdle(); - - 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(SwUiWriterTest3, testTdf39828) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf39828.fodt"); - - // 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 xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), - uno::UNO_QUERY); - uno::Reference xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY); - - CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount()); - - uno::Reference xCellA1(xTextTable->getCellByName("A1"), uno::UNO_QUERY); - // deleted "1", inserted "2" - CPPUNIT_ASSERT_EQUAL(OUString("12"), xCellA1->getString()); - uno::Reference 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 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(SwUiWriterTest3, testTdf146573) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf39828.fodt"); - SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); - - // remove redlines, add a footnote, and change the value - // of the cell with the footnote - dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {}); - Scheduler::ProcessEventsToIdle(); - 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 xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), - uno::UNO_QUERY); - uno::Reference xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY); - - CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount()); - - uno::Reference xCellA1(xTextTable->getCellByName("A1"), uno::UNO_QUERY); - // value "100" and footnote index "1" - CPPUNIT_ASSERT_EQUAL(OUString("1001"), xCellA1->getString()); - uno::Reference xCellA3(xTextTable->getCellByName("A3"), uno::UNO_QUERY); - // This was 4 (missing recalculation) - CPPUNIT_ASSERT_EQUAL(OUString("102"), xCellA3->getString()); - uno::Reference xCellA4(xTextTable->getCellByName("A4"), uno::UNO_QUERY); - // This was 8 (missing recalculation) - CPPUNIT_ASSERT_EQUAL(OUString("204"), xCellA4->getString()); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf148849) -{ - // load a document with a table and an empty paragraph before the table - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf148849.fodt"); - 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 xTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference 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(SwUiWriterTest3, testTdf150576) -{ - // load a document with a table and an empty paragraph before the table - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf148849.fodt"); - 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 xTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference 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", {}); - Scheduler::ProcessEventsToIdle(); - 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(SwUiWriterTest3, testTdf132603) -{ - createSwDoc(); - SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); - - uno::Sequence aPropertyValues - = comphelper::InitPropertySequence({ { "Text", uno::Any(OUString("Comment")) } }); - - dispatchCommand(mxComponent, ".uno:InsertAnnotation", aPropertyValues); - Scheduler::ProcessEventsToIdle(); - - dispatchCommand(mxComponent, ".uno:SelectAll", {}); - Scheduler::ProcessEventsToIdle(); - - // Without the fix in place, it would crash here - dispatchCommand(mxComponent, ".uno:Copy", {}); - Scheduler::ProcessEventsToIdle(); - - tools::JsonWriter aJsonWriter; - pTextDoc->getPostIts(aJsonWriter); - char* pChar = aJsonWriter.extractData(); - std::stringstream aStream(pChar); - free(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("text").c_str()); - CPPUNIT_ASSERT_EQUAL(OString("Comment"), aText); - } -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf117601) -{ - createSwDoc(); - SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); - - uno::Sequence aArgs(comphelper::InitPropertySequence( - { { "Rows", uno::Any(sal_Int32(5)) }, { "Columns", uno::Any(sal_Int32(3)) } })); - - dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); - Scheduler::ProcessEventsToIdle(); - - uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), - uno::UNO_QUERY); - uno::Reference 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 xCellB1(xTextTable->getCellByName("B1"), uno::UNO_QUERY); - xCellB1->setString("test1"); - - uno::Reference 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", {}); - Scheduler::ProcessEventsToIdle(); - - 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", {}); - Scheduler::ProcessEventsToIdle(); - - 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(SwUiWriterTest3, testTdf138130) -{ - createSwDoc(DATA_DIRECTORY, "tdf138130.docx"); - - CPPUNIT_ASSERT_EQUAL(1, getShapes()); - uno::Reference xShape = getShape(1); - - awt::Point aPos = xShape->getPosition(); - - //select shape and change the anchor - dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); - Scheduler::ProcessEventsToIdle(); - - // Without the fix in place, this test would have crashed here - dispatchCommand(mxComponent, ".uno:SetAnchorToPage", {}); - Scheduler::ProcessEventsToIdle(); - - //position has changed - CPPUNIT_ASSERT(aPos.X < xShape->getPosition().X); - CPPUNIT_ASSERT(aPos.Y < xShape->getPosition().Y); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(aPos.X, xShape->getPosition().X); - CPPUNIT_ASSERT_EQUAL(aPos.Y, xShape->getPosition().Y); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf136385) -{ - createSwDoc(DATA_DIRECTORY, "tdf136385.odt"); - - CPPUNIT_ASSERT_EQUAL(1, getShapes()); - uno::Reference xShape = getShape(1); - - awt::Point aPos = xShape->getPosition(); - - //select shape and change the anchor - dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); - Scheduler::ProcessEventsToIdle(); - - dispatchCommand(mxComponent, ".uno:SetAnchorToPage", {}); - Scheduler::ProcessEventsToIdle(); - - //position has changed - CPPUNIT_ASSERT(aPos.X < xShape->getPosition().X); - CPPUNIT_ASSERT(aPos.Y < xShape->getPosition().Y); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - Scheduler::ProcessEventsToIdle(); - - //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(SwUiWriterTest3, testTdf145207) -{ - createSwDoc(DATA_DIRECTORY, "tdf145207.odt"); - SwXTextDocument* pTextDoc = dynamic_cast(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 - dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); - Scheduler::ProcessEventsToIdle(); - - 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(SwUiWriterTest3, testTdf128782) -{ - createSwDoc(DATA_DIRECTORY, "tdf128782.odt"); - SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); - - CPPUNIT_ASSERT_EQUAL(2, getShapes()); - uno::Reference xShape1 = getShape(1); - uno::Reference xShape2 = getShape(2); - - awt::Point aPos[2]; - aPos[0] = xShape1->getPosition(); - aPos[1] = xShape2->getPosition(); - - //select shape 2 and move it down - dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); - dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); - Scheduler::ProcessEventsToIdle(); - - 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", {}); - 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); - // 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(SwUiWriterTest3, testTdf135623) -{ - createSwDoc(DATA_DIRECTORY, "tdf135623.docx"); - SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); - - CPPUNIT_ASSERT_EQUAL(2, getShapes()); - CPPUNIT_ASSERT_EQUAL(2, getPages()); - - uno::Reference xShape1 = getShape(1); - uno::Reference xShape2 = getShape(2); - - awt::Point aPos[2]; - aPos[0] = xShape1->getPosition(); - aPos[1] = xShape2->getPosition(); - - //select shape 1 and move it down - dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); - Scheduler::ProcessEventsToIdle(); - - 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", {}); - 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); - - // 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(SwUiWriterTest3, testTdf133490) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf133490.odt"); - SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); - SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); - - CPPUNIT_ASSERT_EQUAL(1, getShapes()); - - dispatchCommand(mxComponent, ".uno:SelectAll", {}); - - rtl::Reference xTransfer = new SwTransferable(*pWrtShell); - xTransfer->Cut(); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(0, getShapes()); - - TransferableDataHelper aHelper(xTransfer); - SwTransferable::Paste(*pWrtShell, aHelper); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(1, getShapes()); - - SwTransferable::Paste(*pWrtShell, aHelper); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(2, getShapes()); - - uno::Reference xShape1 = getShape(1); - uno::Reference xShape2 = getShape(2); - - awt::Point aPos[2]; - aPos[0] = xShape1->getPosition(); - aPos[1] = xShape2->getPosition(); - - //select shape 2 and move it to the right - dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); - dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); - Scheduler::ProcessEventsToIdle(); - - 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", {}); - Scheduler::ProcessEventsToIdle(); - - // 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", {}); - Scheduler::ProcessEventsToIdle(); - - 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", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(1, getShapes()); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(0, getShapes()); - - dispatchCommand(mxComponent, ".uno:Undo", {}); - Scheduler::ProcessEventsToIdle(); - - CPPUNIT_ASSERT_EQUAL(1, getShapes()); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf132637_protectTrackChanges) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf132637_protectTrackChanges.doc"); - - // The password should only prevent turning off track changes, not open as read-only - CPPUNIT_ASSERT(!pDoc->GetDocShell()->IsReadOnly()); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf127652) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf127652.odt"); - SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell(); - - // get a page cursor - uno::Reference xModel(mxComponent, uno::UNO_QUERY); - uno::Reference xTextViewCursorSupplier( - xModel->getCurrentController(), uno::UNO_QUERY); - uno::Reference 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(SwUiWriterTest3, AtPageTextBoxCrash) -{ - // Load sample file - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "AtPageTextBoxCrash.odt"); - - // Get the format of the shape - const SwFrameFormats& 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 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().GetContentAnchor()); - - // 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(SwUiWriterTest3, testTdf135661) -{ - createSwDoc(DATA_DIRECTORY, "tdf135661.odt"); - - CPPUNIT_ASSERT_EQUAL(1, getShapes()); - uno::Reference 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(SwUiWriterTest3, testTdf133477) -{ - if (getDefaultDeviceBitCount() < 24) - return; - createSwDoc(DATA_DIRECTORY, "tdf133477.fodt"); - - // Save the shape to a BMP. - uno::Reference xGraphicExporter - = drawing::GraphicExportFilter::create(mxComponentContext); - uno::Reference xSourceDoc(getShape(1), uno::UNO_QUERY); - xGraphicExporter->setSourceDocument(xSourceDoc); - - SvMemoryStream aStream; - uno::Reference xOutputStream(new utl::OStreamWrapper(aStream)); - uno::Sequence 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(SwUiWriterTest3, testTdf137964) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf137964.odt"); - SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); - SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); - - CPPUNIT_ASSERT_EQUAL(1, getShapes()); - uno::Reference 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(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(SwUiWriterTest3, testTdf143244) -{ - createSwDoc(DATA_DIRECTORY, "tdf143244.odt"); - - uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), - uno::UNO_QUERY); - uno::Reference 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 xCell(xTextTable->getCellByName("A1"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(Color(0x009353), getProperty(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A2"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A3"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A4"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A5"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A6"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(Color(0xbee3d3), getProperty(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(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", {}); - Scheduler::ProcessEventsToIdle(); - } - - 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", {}); - Scheduler::ProcessEventsToIdle(); - } - - 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(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A2"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A3"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A4"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A5"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty(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(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A7"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A8"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xCell, "BackColor")); - - xCell.set(xTextTable->getCellByName("A9"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(Color(0xbee3d3), getProperty(xCell, "BackColor")); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf136715) -{ - createSwDoc(DATA_DIRECTORY, "tdf136715.odt"); - - uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), - uno::UNO_QUERY); - uno::Reference 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 xCell(xTextTable->getCellByName("A1"), uno::UNO_QUERY); - uno::Reference xParaEnumAccess(xCell->getText(), uno::UNO_QUERY); - uno::Reference xParaEnum = xParaEnumAccess->createEnumeration(); - uno::Reference xPara(xParaEnum->nextElement(), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty(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(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(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(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(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(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(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(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(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(xPara, "CharWeight")); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf138897) -{ - createSwDoc(DATA_DIRECTORY, "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", {}); - Scheduler::ProcessEventsToIdle(); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf136740) -{ - createSwDoc(); - css::uno::Reference xFact(mxComponent, - css::uno::UNO_QUERY_THROW); - css::uno::Reference 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(); - CPPUNIT_ASSERT(nDefTab != 0); - - css::uno::Reference 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(), 1); - - // Paste special as RTF - const auto aPropertyValues = comphelper::InitPropertySequence( - { { "SelectedFormat", - css::uno::Any(static_cast(SotClipboardFormatId::RTF)) } }); - dispatchCommand(mxComponent, ".uno:ClipboardFormatItems", aPropertyValues); - Scheduler::ProcessEventsToIdle(); - - 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: - // - Actual : - // 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(SwUiWriterTest3, testTdf128106) -{ - SwWrtShell* pWrtShell - = createSwDoc(DATA_DIRECTORY, "cross_reference_demo_bmk.odt")->GetDocShell()->GetWrtShell(); - - utl::TempFile tempDir(nullptr, true); - - const auto aPropertyValues = comphelper::InitPropertySequence( - { { "FileName", css::uno::Any(tempDir.GetURL() + "/test.odm") } }); - dispatchCommand(mxComponent, ".uno:NewGlobalDoc", aPropertyValues); - - // new document now! - mxComponent.set(pWrtShell->GetDoc()->GetDocShell()->GetModel()); - CPPUNIT_ASSERT(mxComponent.is()); - - 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 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(fields[0]->GetField())->GetSetRefName()); - CPPUNIT_ASSERT_EQUAL(OUString("Text"), - static_cast(fields[0]->GetField()) - ->GetExpandedTextOfReferencedTextNode(*pWrtShell->GetLayout())); - CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[1]->GetField()->GetSubType()); - CPPUNIT_ASSERT( - static_cast(fields[1]->GetField())->IsRefToHeadingCrossRefBookmark()); - CPPUNIT_ASSERT_EQUAL(OUString("Chapter 2"), - static_cast(fields[1]->GetField())->GetPar2()); - CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[2]->GetField()->GetSubType()); - CPPUNIT_ASSERT_EQUAL(OUString("Bookmarkchapter1"), - static_cast(fields[2]->GetField())->GetSetRefName()); - CPPUNIT_ASSERT_EQUAL(OUString("Chapter 1"), - static_cast(fields[2]->GetField())->GetPar2()); - CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[3]->GetField()->GetSubType()); - CPPUNIT_ASSERT_EQUAL(OUString("bookmarkchapter1_text"), - static_cast(fields[3]->GetField())->GetSetRefName()); - CPPUNIT_ASSERT_EQUAL(OUString("Text"), - static_cast(fields[3]->GetField())->GetPar2()); - CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[4]->GetField()->GetSubType()); - CPPUNIT_ASSERT( - static_cast(fields[4]->GetField())->IsRefToHeadingCrossRefBookmark()); - CPPUNIT_ASSERT_EQUAL(OUString("Chapter 1.1"), - static_cast(fields[4]->GetField())->GetPar2()); - CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[5]->GetField()->GetSubType()); - CPPUNIT_ASSERT( - static_cast(fields[5]->GetField())->IsRefToHeadingCrossRefBookmark()); - CPPUNIT_ASSERT_EQUAL(OUString("Chapter 2"), - static_cast(fields[5]->GetField())->GetPar2()); - - tempDir.EnableKillingFile(); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf103612) -{ - SwDoc* const pGlobalDoc = createSwDoc(DATA_DIRECTORY, "DUMMY.odm"); - 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]/LineBreak[1]", "Line", - "Text before section"); - // the inner section and its content was hidden - assertXPath(pLayout, "/root/page[1]/body/section[2]/txt[1]/LineBreak[1]", "Line", - "Text inside section before ToC"); - assertXPath(pLayout, "/root/page[1]/body/section[3]/txt[1]/LineBreak[1]", "Line", - "Table of Contents"); - assertXPath(pLayout, "/root/page[1]/body/section[4]/txt[1]/LineBreak[1]", "Line", - "First header*1"); - assertXPath(pLayout, "/root/page[1]/body/section[4]/txt[2]/LineBreak[1]", "Line", - "Second header*1"); - assertXPath(pLayout, "/root/page[1]/body/section[5]/txt[2]/LineBreak[1]", "Line", - "Text inside section after ToC"); - assertXPath(pLayout, "/root/page[1]/body/section[6]/txt[1]/LineBreak[1]", "Line", - "Text after section"); -} - -CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf97899) -{ - SwDoc* pDoc = createSwDoc(); - 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 - reload("Office Open XML Text", "tdf97899-tmp.docx"); - uno::Reference xNumberingRules - = getProperty>(getParagraph(1), "NumberingRules"); - CPPUNIT_ASSERT(xNumberingRules->getCount()); - uno::Sequence 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_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx b/sw/qa/extras/uiwriter/uiwriter8.cxx new file mode 100644 index 000000000000..8cef82d03ac7 --- /dev/null +++ b/sw/qa/extras/uiwriter/uiwriter8.cxx @@ -0,0 +1,2371 @@ +/* -*- 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ +constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/extras/uiwriter/data/"; +} // namespace + +/// 8th set of tests asserting the behavior of Writer user interface shells. +class SwUiWriterTest8 : public SwModelTestBase +{ +}; + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf131684) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf131684.docx"); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference 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", {}); + + rtl::Reference xTransfer = new SwTransferable(*pWrtShell); + xTransfer->Cut(); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount()); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); + + TransferableDataHelper aHelper(xTransfer); + SwTransferable::Paste(*pWrtShell, aHelper); + 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]", "id"); + OUString const sectionLower = getXPath(pXmlDoc, "/root/page[1]/body/section[7]", "lower"); + OUString const textId = getXPath(pXmlDoc, "/root/page[1]/body/section[7]/txt[1]", "id"); + OUString const textUpper = getXPath(pXmlDoc, "/root/page[1]/body/section[7]/txt[1]", "upper"); + CPPUNIT_ASSERT_EQUAL(textId, sectionLower); + CPPUNIT_ASSERT_EQUAL(sectionId, textUpper); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132420) +{ + createSwDoc(DATA_DIRECTORY, "tdf132420.odt"); + + CPPUNIT_ASSERT_EQUAL(12, getShapes()); + + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + Scheduler::ProcessEventsToIdle(); + + dispatchCommand(mxComponent, ".uno:Cut", {}); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT_EQUAL(0, getShapes()); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + + //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) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf132744.odt"); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + + // 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", {}); + Scheduler::ProcessEventsToIdle(); + + rtl::Reference xTransfer = new SwTransferable(*pWrtShell); + xTransfer->Cut(); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(0, getShapes()); + + TransferableDataHelper aHelper(xTransfer); + SwTransferable::Paste(*pWrtShell, aHelper); + Scheduler::ProcessEventsToIdle(); + + //Without the fix in place, the image wouldn't be pasted + CPPUNIT_ASSERT_EQUAL(1, getShapes()); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146622) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "TC-table-del-add.docx"); + CPPUNIT_ASSERT(pDoc); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + + CPPUNIT_ASSERT_MESSAGE("redlining should be on", + pDoc->getIDocumentRedlineAccess().IsRedlineOn()); + + uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTables->getCount()); + uno::Reference xTableNames = xTablesSupplier->getTextTables(); + CPPUNIT_ASSERT(xTableNames->hasByName("Table1")); + uno::Reference 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", {}); + Scheduler::ProcessEventsToIdle(); + + dispatchCommand(mxComponent, ".uno:DeleteRows", {}); + CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount()); + + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + Scheduler::ProcessEventsToIdle(); + + 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 + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); + 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", 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", 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", 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", 2); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf147347) +{ + // load a 2-row table, set Hide Changes mode and delete the table with change tracking + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); + 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", 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", 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", 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", 2); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148345) +{ + // load a 2-row table, set Hide Changes mode and delete the first row with change tracking + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); + 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", 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", 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", 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", 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 + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); + 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", {}); + Scheduler::ProcessEventsToIdle(); + + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + // 3-row, overwriting cells of the second row and inserting a new row + // with the 2-row clipboard table content + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 3); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/Text", "Portion", "hello"); + + // Undo + + dispatchCommand(mxComponent, ".uno:Undo", {}); + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + // 2 rows again, no copied text content + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/Text", 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", 2); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt", 2); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/Text", "Portion", + "Some text..."); + // the empty paragraph in A2 + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[2]/Text", 0); + + // insert the table, as a nested one in cell "A2" + dispatchCommand(mxComponent, ".uno:Paste", {}); + Scheduler::ProcessEventsToIdle(); + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab", 1); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab/row", 2); + + // Undo + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + // 2 rows again, no copied text content + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/Text", "Portion", + "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", {}); + Scheduler::ProcessEventsToIdle(); + + 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", 3); + // This was "Some text..." with a nested table + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/Text", "Portion", "hello"); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148791) +{ + // test Paste as Rows Above with centered table alignment + + // load a 2-row table + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); + 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", {}); + Scheduler::ProcessEventsToIdle(); + + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + // Paste as Rows Above results 4-row table with default table alignment + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 4); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[1]/cell[1]/txt/Text", "Portion", "hello"); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[3]/cell[1]/txt/Text", "Portion", "hello"); + + // set table alignment to center, select and copy the table again + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); + + uno::Reference xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY); + + // Default table alignment + CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::FULL, + getProperty(xTextTable, "HoriOrient")); + + //CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xTextTable, "TableTemplateName")); + uno::Reference xTableProps(xTextTable, uno::UNO_QUERY_THROW); + + xTableProps->setPropertyValue("HoriOrient", uno::Any(text::HoriOrientation::CENTER)); + + CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, + getProperty(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", {}); + Scheduler::ProcessEventsToIdle(); + + 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", 8); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[1]/cell[1]/txt/Text", "Portion", "hello"); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[3]/cell[1]/txt/Text", "Portion", "hello"); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[5]/cell[1]/txt/Text", "Portion", "hello"); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[7]/cell[1]/txt/Text", "Portion", "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", {}); + Scheduler::ProcessEventsToIdle(); + + 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", 16); + // there are two nested tables after the paste + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab", 2); + + // tdf#64902 add a test case for repeated table headings + + xTableProps->setPropertyValue("RepeatHeadline", uno::Any(true)); + CPPUNIT_ASSERT(getProperty(xTextTable, "RepeatHeadline")); + + xTableProps->setPropertyValue("HeaderRowCount", uno::Any(sal_Int32(3))); + CPPUNIT_ASSERT_EQUAL(sal_Int32(3), getProperty(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", {}); + Scheduler::ProcessEventsToIdle(); + + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + // repeating table header (and its thead/tbody indentation) doesn't effect row number + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 32); + // there are two nested tables after the paste + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab", 4); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf135014) +{ + createSwDoc(); + + uno::Sequence aArgs( + comphelper::InitPropertySequence({ { "KeyModifier", uno::Any(sal_Int32(0)) } })); + + // Toggle Numbering List + dispatchCommand(mxComponent, ".uno:DefaultBullet", aArgs); + Scheduler::ProcessEventsToIdle(); + + uno::Sequence aArgs2(comphelper::InitPropertySequence( + { { "Param", uno::Any(OUString("NewNumberingStyle")) }, + { "Family", uno::Any(static_cast(SfxStyleFamily::Pseudo)) } })); + + // New Style from selection + dispatchCommand(mxComponent, ".uno:StyleNewByExample", aArgs2); + Scheduler::ProcessEventsToIdle(); + + // Without the fix in place, this test would have failed here + reload("Office Open XML Text", "tdf135014.docx"); + + xmlDocUniquePtr pXmlStyles = parseExport("word/styles.xml"); + assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='NewNumberingStyle']/w:qFormat", 1); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf130629) +{ + createSwDoc(); + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + + uno::Sequence aArgs( + comphelper::InitPropertySequence({ { "KeyModifier", uno::Any(KEY_MOD1) } })); + + dispatchCommand(mxComponent, ".uno:BasicShapes.diamond", aArgs); + Scheduler::ProcessEventsToIdle(); + + 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); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(1, getShapes()); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf145584) +{ + std::shared_ptr pPDFium = vcl::pdf::PDFiumLibrary::get(); + if (!pPDFium) + { + return; + } + SwDoc* const pDoc = createSwDoc(); + 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 aFilterData( + comphelper::InitPropertySequence({ { "Selection", uno::Any(true) } })); + + uno::Sequence 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); + + // Parse the export result. + SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ); + SvMemoryStream aMemory; + aMemory.WriteStream(aFile); + std::unique_ptr pPdfDocument + = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize(), OString()); + CPPUNIT_ASSERT(pPdfDocument); + CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount()); + std::unique_ptr pPdfPage = pPdfDocument->openPage(/*nIndex=*/0); + CPPUNIT_ASSERT(pPdfPage); + CPPUNIT_ASSERT_EQUAL(1, pPdfPage->getObjectCount()); + std::unique_ptr pPdfTextPage = pPdfPage->getTextPage(); + CPPUNIT_ASSERT(pPdfTextPage); + + std::unique_ptr pPageObject = pPdfPage->getObject(0); + OUString sText = pPageObject->getText(pPdfTextPage); + CPPUNIT_ASSERT_EQUAL(OUString("World"), sText); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf140731) +{ + SwDoc* const pDoc = createSwDoc(); + SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtSh); + + pWrtSh->Insert("Lorem"); + + SwXTextDocument* pTextDoc = dynamic_cast(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", {}); + Scheduler::ProcessEventsToIdle(); + + dispatchCommand(mxComponent, ".uno:Copy", {}); + Scheduler::ProcessEventsToIdle(); + + dispatchCommand(mxComponent, ".uno:Paste", {}); + Scheduler::ProcessEventsToIdle(); + + dispatchCommand(mxComponent, ".uno:Paste", {}); + Scheduler::ProcessEventsToIdle(); + } + + dispatchCommand(mxComponent, ".uno:GoToStartOfDoc", {}); + Scheduler::ProcessEventsToIdle(); + + // Format->Text operations on small selections (which would generate <~500 redlines) + // changetracking still working + dispatchCommand(mxComponent, ".uno:TrackChanges", {}); + Scheduler::ProcessEventsToIdle(); + + SwCursorShell* pShell(pDoc->GetEditShell()); + + pShell->SelectTextModel(1, 500); + + dispatchCommand(mxComponent, ".uno:ChangeCaseToTitleCase", {}); + Scheduler::ProcessEventsToIdle(); + + SwEditShell* const pEditShell(pDoc->GetEditShell()); + CPPUNIT_ASSERT_EQUAL(static_cast(120), + pEditShell->GetRedlineCount()); + + //Removing all the redlines. + dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(static_cast(0), pEditShell->GetRedlineCount()); + + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + Scheduler::ProcessEventsToIdle(); + + dispatchCommand(mxComponent, ".uno:ChangeCaseToTitleCase", {}); + Scheduler::ProcessEventsToIdle(); + + // Without the fix in place, on big selections writer would freeze. Now it ignores change tracking. + CPPUNIT_ASSERT_EQUAL(static_cast(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", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("LOREM IPSUM DOLOR SIT AMET")); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf116315) +{ + SwDoc* const pDoc = createSwDoc(); + 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(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) +{ + SwDoc* const pDoc = createSwDoc(); + SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtSh); + + // expands autotext (via F3) + pWrtSh->Insert("AR"); + + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F3); + Scheduler::ProcessEventsToIdle(); + + // was ...'letter of ' + CPPUNIT_ASSERT_EQUAL( + OUString("We hereby acknowledge the receipt of your letter of ."), + getParagraph(1)->getString()); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf141613) +{ + SwDoc* const pDoc = createSwDoc(); + 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 xPageStyle(getStyles("PageStyles")->getByName("Standard"), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(true, getProperty(xPageStyle, "HeaderIsOn")); + CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(1)->getString()); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + + CPPUNIT_ASSERT_EQUAL(false, getProperty(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 xFactory(mxComponent, uno::UNO_QUERY); + uno::Reference xTextGraphic( + xFactory->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY); + + uno::Reference xTextContent(xTextGraphic, uno::UNO_QUERY); + + uno::Reference xPageStyle(getStyles("PageStyles")->getByName("Standard"), + uno::UNO_QUERY); + + xPageStyle->setPropertyValue("HeaderIsOn", uno::Any(true)); + + uno::Reference xHeader( + getProperty>(xPageStyle, "HeaderText")); + CPPUNIT_ASSERT(xHeader.is()); + uno::Reference 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 xFooter( + getProperty>(xPageStyle, "FooterText")); + CPPUNIT_ASSERT(xFooter.is()); + uno::Reference 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) +{ + SwDoc* const pDoc = createSwDoc(); + SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtSh); + + pWrtSh->Insert("Test"); + + CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(1)->getString()); + + uno::Reference xParagraph(getParagraph(1), uno::UNO_QUERY); + + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty(xParagraph, "ParaLeftMargin")); + + dispatchCommand(mxComponent, ".uno:IncrementIndent", {}); + + CPPUNIT_ASSERT_EQUAL(sal_Int32(1251), getProperty(xParagraph, "ParaLeftMargin")); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty(xParagraph, "ParaLeftMargin")); + + // Without the fix in place, this test would have crashed here + dispatchCommand(mxComponent, ".uno:Redo", {}); + + CPPUNIT_ASSERT_EQUAL(sal_Int32(1251), getProperty(xParagraph, "ParaLeftMargin")); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf131771) +{ + createSwDoc(); + + uno::Sequence aArgs(comphelper::InitPropertySequence( + { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } })); + + dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); + Scheduler::ProcessEventsToIdle(); + + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); + + uno::Reference xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY); + + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xTextTable, "TableTemplateName")); + uno::Reference xTableProps(xTextTable, uno::UNO_QUERY_THROW); + xTableProps->setPropertyValue("TableTemplateName", uno::Any(OUString("Default Style"))); + + CPPUNIT_ASSERT_EQUAL(OUString("Default Style"), + getProperty(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(xTextTable, "TableTemplateName")); + + uno::Reference 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(xTextTable2, "TableTemplateName")); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf80663) +{ + createSwDoc(); + + uno::Sequence aArgs(comphelper::InitPropertySequence( + { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } })); + + dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); + Scheduler::ProcessEventsToIdle(); + + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference 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", {}); + Scheduler::ProcessEventsToIdle(); + + 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", {}); + Scheduler::ProcessEventsToIdle(); + + 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) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf130805.odt"); + + const SwFrameFormats& 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); + + auto pTxAnch = pTxBxFrm->GetAnchor().GetContentAnchor(); + auto pShpAnch = pShape->GetAnchor().GetContentAnchor(); + CPPUNIT_ASSERT(pTxAnch); + CPPUNIT_ASSERT(pShpAnch); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("The textbox got apart!", pTxAnch->nNode, pShpAnch->nNode); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf107893) +{ + //Open the sample doc + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf107893.odt"); + + //Get the format of the shape + const SwFrameFormats& rFrmFormats = *pDoc->GetSpzFrameFormats(); + CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1))); + SwFrameFormat* 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 aArgs(comphelper::InitPropertySequence( + { { "Rows", uno::Any(sal_Int32(3)) }, { "Columns", uno::Any(sal_Int32(3)) } })); + + dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); + Scheduler::ProcessEventsToIdle(); + + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); + + dispatchCommand(mxComponent, ".uno:DeleteTable", {}); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount()); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); + + // Without the fix in place, the table would be hidden + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/tab", 1); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, TestTextBoxCrashAfterLineDel) +{ + // Open the desired file + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "txbx_crash.odt"); + + // Get the format of the shape + const SwFrameFormats& rFrmFormats = *pDoc->GetSpzFrameFormats(); + CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1))); + SwFrameFormat* 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(DATA_DIRECTORY, "tdf121546.odt"); + + CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString()); + + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + Scheduler::ProcessEventsToIdle(); + + dispatchCommand(mxComponent, ".uno:Cut", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(1, getParagraphs()); + + // Create a new document + createSwDoc(); + + dispatchCommand(mxComponent, ".uno:Paste", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString()); + + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + Scheduler::ProcessEventsToIdle(); + + dispatchCommand(mxComponent, ".uno:Cut", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(1, getParagraphs()); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString()); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + + SwXTextDocument* pTextDoc = dynamic_cast(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(DATA_DIRECTORY, "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) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf134626.odt"); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + + CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString()); + + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + + rtl::Reference xTransfer = new SwTransferable(*pWrtShell); + xTransfer->Copy(); + Scheduler::ProcessEventsToIdle(); + TransferableDataHelper aHelper(xTransfer); + + // Create a new document + pDoc = createSwDoc(); + 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) + { + SwTransferable::Paste(*pWrtShell, aHelper); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString()); + + SwTransferable::Paste(*pWrtShell, aHelper); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(OUString("AppleApple"), getParagraph(1)->getString()); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString()); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(OUString(""), getParagraph(1)->getString()); + } +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf139566) +{ + SwDoc* pDoc = createSwDoc(); + SwWrtShell* pWrtSh = pDoc->GetDocShell()->GetWrtShell(); + + uno::Sequence aArgs(comphelper::InitPropertySequence( + { { "Rows", uno::Any(sal_Int32(1)) }, { "Columns", uno::Any(sal_Int32(1)) } })); + + dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); + Scheduler::ProcessEventsToIdle(); + + // 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", {}); + Scheduler::ProcessEventsToIdle(); + + uno::Reference xFrames = mxDesktop->getFrames(); + sal_Int32 nFrames = xFrames->getCount(); + + // Create a second window so the first window looses focus + dispatchCommand(mxComponent, ".uno:NewWindow", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(nFrames + 1, xFrames->getCount()); + + dispatchCommand(mxComponent, ".uno:CloseWin", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(nFrames, xFrames->getCount()); + + uno::Reference xModel(mxComponent, uno::UNO_QUERY); + uno::Reference 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 aArgs(comphelper::InitPropertySequence( + { { "Rows", uno::Any(sal_Int32(3)) }, { "Columns", uno::Any(sal_Int32(3)) } })); + + dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); + Scheduler::ProcessEventsToIdle(); + + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference 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", {}); + Scheduler::ProcessEventsToIdle(); + + 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", {}); + Scheduler::ProcessEventsToIdle(); + + 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 aArgs(comphelper::InitPropertySequence( + { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(1)) } })); + + dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); + + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference 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 xCellA1(xTextTable->getCellByName("A1"), uno::UNO_QUERY); + xCellA1->setString("test1"); + + uno::Reference xCellA2(xTextTable->getCellByName("A2"), uno::UNO_QUERY); + xCellA2->setString("test2"); + + dispatchCommand(mxComponent, ".uno:EntireColumn", {}); + dispatchCommand(mxComponent, ".uno:MergeCells", {}); + Scheduler::ProcessEventsToIdle(); + + 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", {}); + Scheduler::ProcessEventsToIdle(); + + 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) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf39828.fodt"); + + // 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 xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY); + + CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount()); + + uno::Reference xCellA1(xTextTable->getCellByName("A1"), uno::UNO_QUERY); + // deleted "1", inserted "2" + CPPUNIT_ASSERT_EQUAL(OUString("12"), xCellA1->getString()); + uno::Reference 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 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) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf39828.fodt"); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + + // remove redlines, add a footnote, and change the value + // of the cell with the footnote + dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {}); + Scheduler::ProcessEventsToIdle(); + 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 xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY); + + CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount()); + + uno::Reference xCellA1(xTextTable->getCellByName("A1"), uno::UNO_QUERY); + // value "100" and footnote index "1" + CPPUNIT_ASSERT_EQUAL(OUString("1001"), xCellA1->getString()); + uno::Reference xCellA3(xTextTable->getCellByName("A3"), uno::UNO_QUERY); + // This was 4 (missing recalculation) + CPPUNIT_ASSERT_EQUAL(OUString("102"), xCellA3->getString()); + uno::Reference xCellA4(xTextTable->getCellByName("A4"), uno::UNO_QUERY); + // This was 8 (missing recalculation) + CPPUNIT_ASSERT_EQUAL(OUString("204"), xCellA4->getString()); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148849) +{ + // load a document with a table and an empty paragraph before the table + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf148849.fodt"); + 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 xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference 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 + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf148849.fodt"); + 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 xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference 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", {}); + Scheduler::ProcessEventsToIdle(); + 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(mxComponent.get()); + + uno::Sequence aPropertyValues + = comphelper::InitPropertySequence({ { "Text", uno::Any(OUString("Comment")) } }); + + dispatchCommand(mxComponent, ".uno:InsertAnnotation", aPropertyValues); + Scheduler::ProcessEventsToIdle(); + + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + Scheduler::ProcessEventsToIdle(); + + // Without the fix in place, it would crash here + dispatchCommand(mxComponent, ".uno:Copy", {}); + Scheduler::ProcessEventsToIdle(); + + tools::JsonWriter aJsonWriter; + pTextDoc->getPostIts(aJsonWriter); + char* pChar = aJsonWriter.extractData(); + std::stringstream aStream(pChar); + free(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("text").c_str()); + CPPUNIT_ASSERT_EQUAL(OString("Comment"), aText); + } +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf117601) +{ + createSwDoc(); + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + + uno::Sequence aArgs(comphelper::InitPropertySequence( + { { "Rows", uno::Any(sal_Int32(5)) }, { "Columns", uno::Any(sal_Int32(3)) } })); + + dispatchCommand(mxComponent, ".uno:InsertTable", aArgs); + Scheduler::ProcessEventsToIdle(); + + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference 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 xCellB1(xTextTable->getCellByName("B1"), uno::UNO_QUERY); + xCellB1->setString("test1"); + + uno::Reference 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", {}); + Scheduler::ProcessEventsToIdle(); + + 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", {}); + Scheduler::ProcessEventsToIdle(); + + 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(DATA_DIRECTORY, "tdf138130.docx"); + + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + uno::Reference xShape = getShape(1); + + awt::Point aPos = xShape->getPosition(); + + //select shape and change the anchor + dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); + Scheduler::ProcessEventsToIdle(); + + // Without the fix in place, this test would have crashed here + dispatchCommand(mxComponent, ".uno:SetAnchorToPage", {}); + Scheduler::ProcessEventsToIdle(); + + //position has changed + CPPUNIT_ASSERT(aPos.X < xShape->getPosition().X); + CPPUNIT_ASSERT(aPos.Y < xShape->getPosition().Y); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(aPos.X, xShape->getPosition().X); + CPPUNIT_ASSERT_EQUAL(aPos.Y, xShape->getPosition().Y); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf136385) +{ + createSwDoc(DATA_DIRECTORY, "tdf136385.odt"); + + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + uno::Reference xShape = getShape(1); + + awt::Point aPos = xShape->getPosition(); + + //select shape and change the anchor + dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); + Scheduler::ProcessEventsToIdle(); + + dispatchCommand(mxComponent, ".uno:SetAnchorToPage", {}); + Scheduler::ProcessEventsToIdle(); + + //position has changed + CPPUNIT_ASSERT(aPos.X < xShape->getPosition().X); + CPPUNIT_ASSERT(aPos.Y < xShape->getPosition().Y); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + + //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(DATA_DIRECTORY, "tdf145207.odt"); + SwXTextDocument* pTextDoc = dynamic_cast(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 + dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); + Scheduler::ProcessEventsToIdle(); + + 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(DATA_DIRECTORY, "tdf128782.odt"); + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + + CPPUNIT_ASSERT_EQUAL(2, getShapes()); + uno::Reference xShape1 = getShape(1); + uno::Reference xShape2 = getShape(2); + + awt::Point aPos[2]; + aPos[0] = xShape1->getPosition(); + aPos[1] = xShape2->getPosition(); + + //select shape 2 and move it down + dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); + dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); + Scheduler::ProcessEventsToIdle(); + + 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", {}); + 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); + // 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(DATA_DIRECTORY, "tdf135623.docx"); + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + + CPPUNIT_ASSERT_EQUAL(2, getShapes()); + CPPUNIT_ASSERT_EQUAL(2, getPages()); + + uno::Reference xShape1 = getShape(1); + uno::Reference xShape2 = getShape(2); + + awt::Point aPos[2]; + aPos[0] = xShape1->getPosition(); + aPos[1] = xShape2->getPosition(); + + //select shape 1 and move it down + dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); + Scheduler::ProcessEventsToIdle(); + + 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", {}); + 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); + + // 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) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf133490.odt"); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + + rtl::Reference xTransfer = new SwTransferable(*pWrtShell); + xTransfer->Cut(); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(0, getShapes()); + + TransferableDataHelper aHelper(xTransfer); + SwTransferable::Paste(*pWrtShell, aHelper); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + + SwTransferable::Paste(*pWrtShell, aHelper); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(2, getShapes()); + + uno::Reference xShape1 = getShape(1); + uno::Reference xShape2 = getShape(2); + + awt::Point aPos[2]; + aPos[0] = xShape1->getPosition(); + aPos[1] = xShape2->getPosition(); + + //select shape 2 and move it to the right + dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); + dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {}); + Scheduler::ProcessEventsToIdle(); + + 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", {}); + Scheduler::ProcessEventsToIdle(); + + // 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", {}); + Scheduler::ProcessEventsToIdle(); + + 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", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(0, getShapes()); + + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + + CPPUNIT_ASSERT_EQUAL(1, getShapes()); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132637_protectTrackChanges) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf132637_protectTrackChanges.doc"); + + // The password should only prevent turning off track changes, not open as read-only + CPPUNIT_ASSERT(!pDoc->GetDocShell()->IsReadOnly()); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf127652) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf127652.odt"); + SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + + // get a page cursor + uno::Reference xModel(mxComponent, uno::UNO_QUERY); + uno::Reference xTextViewCursorSupplier( + xModel->getCurrentController(), uno::UNO_QUERY); + uno::Reference 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 + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "AtPageTextBoxCrash.odt"); + + // Get the format of the shape + const SwFrameFormats& 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 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().GetContentAnchor()); + + // 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(DATA_DIRECTORY, "tdf135661.odt"); + + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + uno::Reference 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(DATA_DIRECTORY, "tdf133477.fodt"); + + // Save the shape to a BMP. + uno::Reference xGraphicExporter + = drawing::GraphicExportFilter::create(mxComponentContext); + uno::Reference xSourceDoc(getShape(1), uno::UNO_QUERY); + xGraphicExporter->setSourceDocument(xSourceDoc); + + SvMemoryStream aStream; + uno::Reference xOutputStream(new utl::OStreamWrapper(aStream)); + uno::Sequence 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) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf137964.odt"); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + uno::Reference 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(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(DATA_DIRECTORY, "tdf143244.odt"); + + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference 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 xCell(xTextTable->getCellByName("A1"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(Color(0x009353), getProperty(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A2"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A3"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A4"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A5"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A6"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(Color(0xbee3d3), getProperty(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(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", {}); + Scheduler::ProcessEventsToIdle(); + } + + 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", {}); + Scheduler::ProcessEventsToIdle(); + } + + 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(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A2"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A3"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A4"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A5"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty(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(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A7"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A8"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty(xCell, "BackColor")); + + xCell.set(xTextTable->getCellByName("A9"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(Color(0xbee3d3), getProperty(xCell, "BackColor")); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf136715) +{ + createSwDoc(DATA_DIRECTORY, "tdf136715.odt"); + + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference 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 xCell(xTextTable->getCellByName("A1"), uno::UNO_QUERY); + uno::Reference xParaEnumAccess(xCell->getText(), uno::UNO_QUERY); + uno::Reference xParaEnum = xParaEnumAccess->createEnumeration(); + uno::Reference xPara(xParaEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty(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(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(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(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(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(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(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(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(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(xPara, "CharWeight")); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf138897) +{ + createSwDoc(DATA_DIRECTORY, "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", {}); + Scheduler::ProcessEventsToIdle(); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf136740) +{ + createSwDoc(); + css::uno::Reference xFact(mxComponent, + css::uno::UNO_QUERY_THROW); + css::uno::Reference 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(); + CPPUNIT_ASSERT(nDefTab != 0); + + css::uno::Reference 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(), 1); + + // Paste special as RTF + const auto aPropertyValues = comphelper::InitPropertySequence( + { { "SelectedFormat", + css::uno::Any(static_cast(SotClipboardFormatId::RTF)) } }); + dispatchCommand(mxComponent, ".uno:ClipboardFormatItems", aPropertyValues); + Scheduler::ProcessEventsToIdle(); + + 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: + // - Actual : + // 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) +{ + SwWrtShell* pWrtShell + = createSwDoc(DATA_DIRECTORY, "cross_reference_demo_bmk.odt")->GetDocShell()->GetWrtShell(); + + utl::TempFile tempDir(nullptr, true); + + const auto aPropertyValues = comphelper::InitPropertySequence( + { { "FileName", css::uno::Any(tempDir.GetURL() + "/test.odm") } }); + dispatchCommand(mxComponent, ".uno:NewGlobalDoc", aPropertyValues); + + // new document now! + mxComponent.set(pWrtShell->GetDoc()->GetDocShell()->GetModel()); + CPPUNIT_ASSERT(mxComponent.is()); + + 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 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(fields[0]->GetField())->GetSetRefName()); + CPPUNIT_ASSERT_EQUAL(OUString("Text"), + static_cast(fields[0]->GetField()) + ->GetExpandedTextOfReferencedTextNode(*pWrtShell->GetLayout())); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[1]->GetField()->GetSubType()); + CPPUNIT_ASSERT( + static_cast(fields[1]->GetField())->IsRefToHeadingCrossRefBookmark()); + CPPUNIT_ASSERT_EQUAL(OUString("Chapter 2"), + static_cast(fields[1]->GetField())->GetPar2()); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[2]->GetField()->GetSubType()); + CPPUNIT_ASSERT_EQUAL(OUString("Bookmarkchapter1"), + static_cast(fields[2]->GetField())->GetSetRefName()); + CPPUNIT_ASSERT_EQUAL(OUString("Chapter 1"), + static_cast(fields[2]->GetField())->GetPar2()); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[3]->GetField()->GetSubType()); + CPPUNIT_ASSERT_EQUAL(OUString("bookmarkchapter1_text"), + static_cast(fields[3]->GetField())->GetSetRefName()); + CPPUNIT_ASSERT_EQUAL(OUString("Text"), + static_cast(fields[3]->GetField())->GetPar2()); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[4]->GetField()->GetSubType()); + CPPUNIT_ASSERT( + static_cast(fields[4]->GetField())->IsRefToHeadingCrossRefBookmark()); + CPPUNIT_ASSERT_EQUAL(OUString("Chapter 1.1"), + static_cast(fields[4]->GetField())->GetPar2()); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[5]->GetField()->GetSubType()); + CPPUNIT_ASSERT( + static_cast(fields[5]->GetField())->IsRefToHeadingCrossRefBookmark()); + CPPUNIT_ASSERT_EQUAL(OUString("Chapter 2"), + static_cast(fields[5]->GetField())->GetPar2()); + + tempDir.EnableKillingFile(); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf103612) +{ + SwDoc* const pGlobalDoc = createSwDoc(DATA_DIRECTORY, "DUMMY.odm"); + 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]/LineBreak[1]", "Line", + "Text before section"); + // the inner section and its content was hidden + assertXPath(pLayout, "/root/page[1]/body/section[2]/txt[1]/LineBreak[1]", "Line", + "Text inside section before ToC"); + assertXPath(pLayout, "/root/page[1]/body/section[3]/txt[1]/LineBreak[1]", "Line", + "Table of Contents"); + assertXPath(pLayout, "/root/page[1]/body/section[4]/txt[1]/LineBreak[1]", "Line", + "First header*1"); + assertXPath(pLayout, "/root/page[1]/body/section[4]/txt[2]/LineBreak[1]", "Line", + "Second header*1"); + assertXPath(pLayout, "/root/page[1]/body/section[5]/txt[2]/LineBreak[1]", "Line", + "Text inside section after ToC"); + assertXPath(pLayout, "/root/page[1]/body/section[6]/txt[1]/LineBreak[1]", "Line", + "Text after section"); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf97899) +{ + SwDoc* pDoc = createSwDoc(); + 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 + reload("Office Open XML Text", "tdf97899-tmp.docx"); + uno::Reference xNumberingRules + = getProperty>(getParagraph(1), "NumberingRules"); + CPPUNIT_ASSERT(xNumberingRules->getCount()); + uno::Sequence 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_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */