namespace
{ /// 8th set of tests asserting the behavior of Writer user interface shells. class SwUiWriterTest8 : public SwModelTestBase
{ public:
SwUiWriterTest8()
: SwModelTestBase(u"/sw/qa/extras/uiwriter/data/"_ustr)
{
}
};
dispatchCommand(mxComponent, u".uno:DeleteRows"_ustr, {}); // This was 2 (deleting the already deleted table with change tracking)
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTables->getCount());
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());
// check that the first table was deleted with change tracking
dispatchCommand(mxComponent, u".uno:AcceptAllTrackedChanges"_ustr, {});
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
// now only the second table deleted by AcceptAllTrackedChanges
dispatchCommand(mxComponent, u".uno:AcceptAllTrackedChanges"_ustr, {});
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount());
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146962)
{ // load a 2-row table, set Hide Changes mode and delete the first row with change tracking
createSwDoc("tdf116789.fodt");
SwDoc* pDoc = getSwDoc();
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
CPPUNIT_ASSERT(pWrtShell);
// enable redlining
dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
CPPUNIT_ASSERT_MESSAGE("redlining should be on",
pDoc->getIDocumentRedlineAccess().IsRedlineOn()); // hide changes
dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
// Without the fix in place, this test would have crashed here
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
// FIXME: Show Changes, otherwise ~SwTableNode() would have crashed
dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148345)
{ // load a 2-row table, set Hide Changes mode and delete the first row with change tracking
createSwDoc("tdf116789.fodt");
SwDoc* pDoc = getSwDoc();
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
CPPUNIT_ASSERT(pWrtShell);
// enable redlining
dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
CPPUNIT_ASSERT_MESSAGE("redlining should be on",
pDoc->getIDocumentRedlineAccess().IsRedlineOn()); // hide changes
dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
pXmlDoc = parseLayoutDump(); // only a single row is visible again
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 1);
// tdf#148227 check Reject All of tracked table row deletion
dispatchCommand(mxComponent, u".uno:RejectAllTrackedChanges"_ustr, {});
pXmlDoc = parseLayoutDump(); // This was 1
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf141391)
{ // table insertion in the first paragraph of the cell // overwrites the row content, instead of inserting a nested table
// select the table, and copy it into at paragraph start of cell "A2"
dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
dispatchCommand(mxComponent, u".uno:Copy"_ustr, {}); // remove the selection and positionate the cursor at beginning of A2
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
xmlDocUniquePtr pXmlDoc = parseLayoutDump(); // 3-row, overwriting cells of the second row and inserting a new row // with the 2-row clipboard table content
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 3);
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout", "portion", u"hello");
// Undo
dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
pXmlDoc = parseLayoutDump(); // 2 rows again, no copied text content
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/SwParaPortion", 0);
// insert the 2-row table into the second paragraph of cell "A2" as a nested table // For this it's enough to positionate the text cursor not in the first paragraph
// insert some text and an empty paragraph
pWrtShell->Insert(u"Some text..."_ustr);
pWrtShell->SplitNode();
Scheduler::ProcessEventsToIdle();
pXmlDoc = parseLayoutDump();
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt", 2);
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/SwParaPortion/SwLineLayout", "portion", u"Some text..."); // the empty paragraph in A2
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[2]/SwParaPortion", 0);
// insert the table, as a nested one in cell "A2"
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
pXmlDoc = parseLayoutDump();
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab", 1);
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab/row", 2);
// copy the 2-row table into the first paragraph of cell "A2", // but not at paragraph start (changed behaviour)
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
pWrtShell->Insert(u"and some text again in the first paragraph to be sure..."_ustr);
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
pXmlDoc = parseLayoutDump();
// 3-row, overwriting cells of the second row and inserting a new row // with the 2-row clipboard table content
// This was 2 (nested table)
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 3); // This was "Some text..." with a nested table
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout", "portion", u"hello");
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148791)
{ // test Paste as Rows Above with centered table alignment
// set table alignment to center, select and copy the table again
uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
dispatchCommand(mxComponent, u".uno:Copy"_ustr, {}); // remove the selection and positionate the cursor at beginning of A2
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
pWrtShell->Up(/*bSelect=*/false);
pWrtShell->Up(/*bSelect=*/false);
pWrtShell->Up(/*bSelect=*/false);
dispatchCommand(mxComponent, u".uno:PasteRowsBefore"_ustr, {});
pXmlDoc = parseLayoutDump(); // This was 5 (inserting only a single row for the 4-row clipboard content, and // overwriting 3 existing rows)
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 8);
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[1]/cell[1]/txt/SwParaPortion/SwLineLayout", "portion", u"hello");
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[3]/cell[1]/txt/SwParaPortion/SwLineLayout", "portion", u"hello");
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[5]/cell[1]/txt/SwParaPortion/SwLineLayout", "portion", u"hello");
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[7]/cell[1]/txt/SwParaPortion/SwLineLayout", "portion", u"hello");
// tdf#64902 add a test case for nested tables
// insert a nested table, and copy as paste as rows above the whole table with it
dispatchCommand(mxComponent, u".uno:PasteNestedTable"_ustr, {});
dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
dispatchCommand(mxComponent, u".uno:Copy"_ustr, {}); // remove the selection and positionate the cursor at beginning of A2
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false); // skip 7 table rows plus 4 rows of the nested table for (int i = 0; i < 7 + 4; ++i)
pWrtShell->Up(/*bSelect=*/false);
dispatchCommand(mxComponent, u".uno:PasteRowsBefore"_ustr, {});
pXmlDoc = parseLayoutDump(); // rows of the nested table doesn't effect row number of the main table
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 16); // there are two nested tables after the paste
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab", 2);
// tdf#64902 add a test case for repeated table headings
dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
dispatchCommand(mxComponent, u".uno:Copy"_ustr, {}); // remove the selection and positionate the cursor at beginning of A2
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false); // skip 15 table rows plus 4 * 2 rows of the nested tables for (int i = 0; i < 15 + 4 * 2; ++i)
pWrtShell->Up(/*bSelect=*/false);
dispatchCommand(mxComponent, u".uno:PasteRowsBefore"_ustr, {});
pXmlDoc = parseLayoutDump(); // repeating table header (and its thead/tbody indentation) doesn't effect row number
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 32); // there are two nested tables after the paste
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab", 4);
}
// Shape toolbar is active, use ESC before inserting a new shape
SwXTextDocument* pTextDoc = getSwTextDoc();
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_ESCAPE);
Scheduler::ProcessEventsToIdle();
// Without the fix in place, this test would have crashed here
dispatchCommand(mxComponent, u".uno:BasicShapes.diamond"_ustr, aArgs);
// Without the fix in place, this test would have bad order // (starting with the outlines of text frames)
CPPUNIT_ASSERT_EQUAL(u"Article 1. Definitions\n" " Apple\n" " Bread\n" " Cable\n" " Cable\n"// ??? "Article 2. Three style separators in one line!\n" " Heading 2\n" " Heading 2 Again\n"_ustr,
pPdfDocument->getBookmarks());
}
// Without the fix in place, this test would have bad order // (starting with the outlines of text frames)
CPPUNIT_ASSERT_EQUAL(u"H1\n" " H2\n" " H3\n" " Lorem\n" " Vestibulum\n" " Integer\n" " Aliquam\n" " Donec\n" " Praesent\n" " H3\n" " Lorem\n" " Vestibulum\n" " Integer\n" " Aliquam\n" " Donec\n" " Praesent\n" "H1\n" " H2\n" " H3\n" " Lorem\n" " Vestibulum\n" " Integer\n" " Aliquam\n" " Donec\n" " Praesent\n"_ustr,
pPdfDocument->getBookmarks());
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf152575)
{ // FIXME: the DPI check should be removed when either (1) the test is fixed to work with // non-default DPI; or (2) unit tests on Windows are made to use svp VCL plugin. if (!IsDefaultDPI()) return;
std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get(); if (!pPDFium) return;
createSwDoc("152575.fodt");
// Save as PDF.
uno::Sequence<beans::PropertyValue> aFilterData(
comphelper::InitPropertySequence({ { "ExportNotesInMargin", uno::Any(true) } }));
// Without the fix in place, this test would have crashed here
dispatchCommand(mxComponent, u".uno:ExportToPDF"_ustr, aDescriptor);
std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parsePDFExport();
CPPUNIT_ASSERT_EQUAL(3, pPdfDocument->getPageCount());
std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/1);
CPPUNIT_ASSERT(pPdfPage); // Without the fix for tdf#152575 this would be only 42 objects
CPPUNIT_ASSERT_EQUAL(50, pPdfPage->getObjectCount());
}
// generating a big text with ~60k words and several paragraphs for (sal_Int32 i = 0; i < 8; ++i)
{
dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
// Format->Text operations on small selections (which would generate <~500 redlines) // changetracking still working
dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
// Without the fix in place, on big selections writer would freeze. Now it ignores change tracking.
CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(0), pEditShell->GetRedlineCount());
// The patch has no effects on the Format->Text operations
CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Lorem Ipsum Dolor Sit Amet"));
{
SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() }; // numrule from paragraph style, but not from direct formatting auto pSet{ rNode.GetpSwAttrSet() };
CPPUNIT_ASSERT(pSet); // list id was set
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false)); // the numrule is set on the paragraph style, not on the paragraph
CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_PARATR_NUMRULE, false));
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, true));
CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT,
pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, true));
CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false));
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true));
CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName().toString());
CPPUNIT_ASSERT_EQUAL(u"Item We confirm receipt of your application material."_ustr,
rNode.GetText());
pNumRule = rNode.GetNumRule();
pTextLeftMargin = &rNode.GetAttr(RES_MARGIN_TEXTLEFT);
pFirstLineIndent = &rNode.GetAttr(RES_MARGIN_FIRSTLINE);
}
pWrtShell->FwdPara();
{
SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() }; auto pSet{ rNode.GetpSwAttrSet() };
CPPUNIT_ASSERT(pSet); // list id was set
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false)); // middle paragraph was pasted - has numrule and indents applied directly
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, false));
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false));
CPPUNIT_ASSERT_EQUAL(u"Default Paragraph Style"_ustr,
rNode.GetTextColl()->GetName().toString());
CPPUNIT_ASSERT(rNode.GetText().startsWith("As more applicants applied"));
CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule());
CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->ResolveTextLeft({}),
rNode.GetAttr(RES_MARGIN_TEXTLEFT).ResolveTextLeft({}));
CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->ResolveTextFirstLineOffset({}),
rNode.GetAttr(RES_MARGIN_FIRSTLINE).ResolveTextFirstLineOffset({}));
}
pWrtShell->FwdPara();
{
SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() }; // numrule from paragraph style, but not from direct formatting auto pSet{ rNode.GetpSwAttrSet() };
CPPUNIT_ASSERT(pSet); // list id was set
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false)); // the numrule is set on the paragraph style, not on the paragraph
CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_PARATR_NUMRULE, false));
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, true));
CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT,
pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, true));
CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false));
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true));
CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName().toString());
CPPUNIT_ASSERT(rNode.GetText().endsWith("as soon as we have come to a decision."));
CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule());
CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->ResolveTextLeft({}),
rNode.GetAttr(RES_MARGIN_TEXTLEFT).ResolveTextLeft({}));
CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->ResolveTextFirstLineOffset({}),
rNode.GetAttr(RES_MARGIN_FIRSTLINE).ResolveTextFirstLineOffset({}));
}
pWrtShell->FwdPara();
{
SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() }; // numrule from paragraph style, but not from direct formatting auto pSet{ rNode.GetpSwAttrSet() };
CPPUNIT_ASSERT(pSet); // list id was set
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false)); // the numrule is set on the paragraph style, not on the paragraph
CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_PARATR_NUMRULE, false));
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, true));
CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT,
pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, true));
CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false));
CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true));
CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName().toString());
CPPUNIT_ASSERT_EQUAL(u"more"_ustr, rNode.GetText()); // pre-existing list item
CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule());
CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->ResolveTextLeft({}),
rNode.GetAttr(RES_MARGIN_TEXTLEFT).ResolveTextLeft({}));
CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->ResolveTextFirstLineOffset({}),
rNode.GetAttr(RES_MARGIN_FIRSTLINE).ResolveTextFirstLineOffset({}));
}
}
// was ...'letter of <placeholder:"November 21, 2004":"Click placeholder and overwrite">'
CPPUNIT_ASSERT_EQUAL(
u"We hereby acknowledge the receipt of your letter of <November 21, 2004>."_ustr,
getParagraph(1)->getString());
}
// create an additional non-header undo point
pWrtShell->Insert(u"crash_test"_ustr); // three undo points
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rUndoManager.GetUndoActionCount());
// undo all the changes in one pass
uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({
{ "Undo", uno::Any(sal_Int32(4)) },
}));
dispatchCommand(mxComponent, u".uno:Undo"_ustr, aPropertyValues); // undo all 4 actions
CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rUndoManager.GetUndoActionCount());
// Crash avoided by clearing the entire redo stack. This redo request will do nothing. // Without the fix in place, this test would have crashed here
dispatchCommand(mxComponent, u".uno:Redo"_ustr, {}); // redo first (Header) change // Since Redo is "cleared", the redo did nothing, thus the Header remains off
CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPageStyle, u"HeaderIsOn"_ustr));
}
// Without the fix in place, this test would have crashed here
dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
CPPUNIT_ASSERT_EQUAL(u""_ustr, getParagraph(1)->getString());
}
// Without the fix in place, this test would have failed with // - Expected: Default Style // - Actual :
CPPUNIT_ASSERT_EQUAL(u"Default Style"_ustr,
getProperty<OUString>(xTextTable2, u"TableTemplateName"_ustr));
}
// check that table was created and inserted into the document
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
// create another document
createSwDoc();
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
// without the test, writer freezes on redo table paste into new doc
dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables2->getCount());
}
//Get the format of the shape constauto& rFrmFormats = *pDoc->GetSpzFrameFormats();
CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1))); auto pShape = rFrmFormats.front();
CPPUNIT_ASSERT(pShape);
//Add a textbox
SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
SwFrameFormat* pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
CPPUNIT_ASSERT(pTxBxFrm);
//Remove the textbox using Undo
dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
//Add again
SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
//This was nullptr because of unsuccessful re-adding
CPPUNIT_ASSERT_MESSAGE("Textbox cannot be readd after Undo!", pTxBxFrm);
}
// Without the fix in place, the table would be hidden
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
assertXPath(pXmlDoc, "/root/page[1]/body/tab", 1);
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, TestTextBoxCrashAfterLineDel)
{ // Open the desired file
createSwDoc("txbx_crash.odt");
SwDoc* pDoc = getSwDoc();
// Get the format of the shape constauto& rFrmFormats = *pDoc->GetSpzFrameFormats();
CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1))); auto pShape = rFrmFormats.front();
CPPUNIT_ASSERT(pShape);
// Without the fix in place, this test would have failed with // - Expected: Some Text // - Actual : Table of Contents
CPPUNIT_ASSERT_EQUAL(u"Some Text"_ustr, getParagraph(1)->getString());
// tdf#160095: Without the fix in place, this test would have crashed here
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_MOD2 | awt::Key::RETURN);
Scheduler::ProcessEventsToIdle();
// Without the fix in place, this test would have crashed here
SwXTextDocument* pTextDoc = getSwTextDoc();
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RETURN);
Scheduler::ProcessEventsToIdle();
// Create a new document
createSwDoc();
pWrtShell = getSwDocShell()->GetWrtShell();
CPPUNIT_ASSERT(pWrtShell);
// Without the fix in place, this test would have crashed here for (sal_Int32 i = 0; i < 5; ++i)
{
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
// show changes
pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete
| RedlineFlags::ShowInsert);
CPPUNIT_ASSERT_MESSAGE("redlining should be off",
!pDoc->getIDocumentRedlineAccess().IsRedlineOn());
CPPUNIT_ASSERT_MESSAGE( "redlines should be visible",
IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY); // deleted "1", inserted "2"
CPPUNIT_ASSERT_EQUAL(u"12"_ustr, xCellA1->getString());
uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName(u"A3"_ustr), uno::UNO_QUERY); // This was 14 (bad sum: 2 + A1, where A1 was 12 instead of the correct 2)
CPPUNIT_ASSERT_EQUAL(u"4"_ustr, xCellA3->getString());
uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName(u"A4"_ustr), uno::UNO_QUERY); // This was 28 (bad sum: 2 + A1 + A3, where A1 was 12 and A3 was 14)
CPPUNIT_ASSERT_EQUAL(u"8"_ustr, xCellA4->getString());
}
uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY); // value "100" and footnote index "1"
CPPUNIT_ASSERT_EQUAL(u"1001"_ustr, xCellA1->getString());
uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName(u"A3"_ustr), uno::UNO_QUERY); // This was 4 (missing recalculation)
CPPUNIT_ASSERT_EQUAL(u"102"_ustr, xCellA3->getString());
uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName(u"A4"_ustr), uno::UNO_QUERY); // This was 8 (missing recalculation)
CPPUNIT_ASSERT_EQUAL(u"204"_ustr, xCellA4->getString());
}
// Without the fix in place, this test would have failed with // - Expected: 6 // - Actual : 2
CPPUNIT_ASSERT_EQUAL(u"6"_ustr, xCellA4->getString());
uno::Reference<text::XTextRange> xCellA5(xTextTable->getCellByName(u"A5"_ustr), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"7"_ustr, xCellA5->getString());
// tdf#158336: Without the fix in place, this test would have failed with // - Expected: 2 // - Actual : ** Expression is faulty **
CPPUNIT_ASSERT_EQUAL(u"2"_ustr, xCellA2->getString());
xCellA3.set(xTextTable->getCellByName(u"A3"_ustr), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"3"_ustr, xCellA3->getString());
xCellA4.set(xTextTable->getCellByName(u"A4"_ustr), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"6"_ustr, xCellA4->getString());
xCellA5.set(xTextTable->getCellByName(u"A5"_ustr), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"7"_ustr, xCellA5->getString());
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148799)
{ // load a document with table formulas with comma delimiter, // but with a document language with default point delimiter
createSwDoc("tdf148799.docx");
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
// check formula update
// put cursor in the first table row
pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf151993)
{ // load a document with table formulas with comma delimiter // (with a document language with default comma delimiter)
createSwDoc("tdf151993.docx");
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
// check formula update
// put cursor in the first table row
pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
// This was 0
uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName(u"A2"_ustr), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"30"_ustr, xCellA1->getString());
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148849)
{ // load a document with a table and an empty paragraph before the table
createSwDoc("tdf148849.fodt");
SwDoc* pDoc = getSwDoc();
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
// record changes
pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
| RedlineFlags::ShowInsert);
CPPUNIT_ASSERT_MESSAGE("redlining should be on",
pDoc->getIDocumentRedlineAccess().IsRedlineOn()); // hide changes
dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
// put cursor in the first table row
pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
// delete a table row
pWrtShell->DeleteRow();
// check cursor position
// This was "", because the text cursor jumped to the start of the document // after deleting a table row instead of remaining in the next table row
SwNode& rNode = pWrtShell->GetCursor()->GetPoint()->GetNode();
CPPUNIT_ASSERT_EQUAL(u"Row 2"_ustr, rNode.GetTextNode()->GetText());
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf150576)
{ // load a document with a table and an empty paragraph before the table
createSwDoc("tdf148849.fodt");
SwDoc* pDoc = getSwDoc();
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
// record changes
pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
| RedlineFlags::ShowInsert);
CPPUNIT_ASSERT_MESSAGE("redlining should be on",
pDoc->getIDocumentRedlineAccess().IsRedlineOn()); // hide changes
dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
// Check deletion of the first row, if the second row deleted already
// put cursor in the second table row
pWrtShell->Down(/*bSelect=*/false, /*nCount=*/2);
SwNode& rNode = pWrtShell->GetCursor()->GetPoint()->GetNode();
CPPUNIT_ASSERT_EQUAL(u"Row 2"_ustr, rNode.GetTextNode()->GetText());
// delete the second table row
pWrtShell->DeleteRow();
// put cursor in the first row
pWrtShell->Up(/*bSelect=*/false, /*nCount=*/1);
SwNode& rNode3 = pWrtShell->GetCursor()->GetPoint()->GetNode();
CPPUNIT_ASSERT_EQUAL(u"12"_ustr, rNode3.GetTextNode()->GetText());
// delete the first row
pWrtShell->DeleteRow();
// This was empty (cursor jumped in the start of the document instead of // the next not deleted row)
SwNode& rNode4 = pWrtShell->GetCursor()->GetPoint()->GetNode();
CPPUNIT_ASSERT_EQUAL(u"Row 3"_ustr, rNode4.GetTextNode()->GetText());
// delete the second row
pWrtShell->DeleteRow();
SwNode& rNode7 = pWrtShell->GetCursor()->GetPoint()->GetNode();
CPPUNIT_ASSERT_EQUAL(u"Row 3"_ustr, rNode7.GetTextNode()->GetText());
// delete the third, i.e. last row
pWrtShell->DeleteRow();
SwNode& rNode8 = pWrtShell->GetCursor()->GetPoint()->GetNode();
// This was empty (cursor jumped in the start of the document instead of // the previous not deleted row)
CPPUNIT_ASSERT_EQUAL(u"12"_ustr, rNode8.GetTextNode()->GetText());
}
//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);
}
//select one shape and use the TAB key to iterate over the different shapes
selectShape(1);
SwXTextDocument* pTextDoc = getSwTextDoc(); for (sal_Int32 i = 0; i < 10; ++i)
{ // Without the fix in place, this test would have crashed here
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
Scheduler::ProcessEventsToIdle();
}
}
CPPUNIT_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);
}
// Without the fix in place, this test would have failed here // - Expected: 1351 // - Actual : 2233
CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);
//select shape 2 and move it to the right
selectShape(2);
SwXTextDocument* pTextDoc = getSwTextDoc(); for (sal_Int32 i = 0; i < 5; ++i)
{
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RIGHT);
Scheduler::ProcessEventsToIdle();
}
CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y); //X position in shape 2 has changed
CPPUNIT_ASSERT(aPos[1].X < xShape2->getPosition().X);
CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);
for (sal_Int32 i = 0; i < 4; ++i)
{
dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
// Without the fix in place, undo action would have changed shape1's position // and this test would have failed with // - Expected: -139 // - Actual : 1194
CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
CPPUNIT_ASSERT(aPos[1].X < xShape2->getPosition().X);
CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);
}
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);
// get a page cursor
uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
xModel->getCurrentController(), uno::UNO_QUERY);
uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(),
uno::UNO_QUERY);
// go to the start of page 4
xCursor->jumpToPage(4);
xCursor->jumpToStartOfPage();
// mark a section that overlaps multiple pages
pWrtShell->Down(false, 2);
pWrtShell->Up(true, 5);
// delete the marked section
pWrtShell->DelRight();
// go to the start of page 4
xCursor->jumpToPage(4);
xCursor->jumpToStartOfPage();
// move up to page 3
pWrtShell->Up(false, 5);
// check that we are on the third page // in the bug one issue was that the cursor was placed incorrectly, so // moving up to the previous page would not work any more
sal_uInt16 assertPage = 3;
SwCursorShell* pShell(pDoc->GetEditShell());
CPPUNIT_ASSERT(pShell);
sal_uInt16 currentPage = pShell->GetPageNumSeqNonEmpty();
CPPUNIT_ASSERT_EQUAL_MESSAGE("We are on the wrong page!", assertPage, currentPage);
}
// Get the format of the shape constauto& rFrmFormats = *pDoc->GetSpzFrameFormats();
CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1))); auto pShape = rFrmFormats.front();
CPPUNIT_ASSERT(pShape);
// Add a textbox to the shape
SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject()); auto pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
CPPUNIT_ASSERT(pTxBxFrm);
// Change its anchor to page
uno::Reference<beans::XPropertySet> xShpProps(getShape(1), uno::UNO_QUERY_THROW);
xShpProps->setPropertyValue(
u"AnchorType"_ustr, uno::Any(text::TextContentAnchorType::TextContentAnchorType_AT_PAGE));
// The page anchored objects must not have content anchor // unless this will lead to crash later, for example on // removing the paragraph where it is anchored to...
CPPUNIT_ASSERT_EQUAL(RndStdIds::FLY_AT_PAGE, pTxBxFrm->GetAnchor().GetAnchorId());
CPPUNIT_ASSERT(!pTxBxFrm->GetAnchor().GetAnchorNode());
// Remove the paragraph where the textframe should be anchored // before. Now with the patch it must not crash... auto xPara = getParagraph(1);
xPara->getText()->setString(OUString());
}
//Without the fix in place, the shape position would have been 0,0
CPPUNIT_ASSERT_EQUAL(sal_Int32(3424), xShape->getPosition().X);
CPPUNIT_ASSERT_EQUAL(sal_Int32(1545), xShape->getPosition().Y);
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf133477)
{ if (getDefaultDeviceBitCount() < 24) return;
createSwDoc("tdf133477.fodt");
// Save the shape to a BMP.
uno::Reference<drawing::XGraphicExportFilter> xGraphicExporter
= drawing::GraphicExportFilter::create(m_xContext);
uno::Reference<lang::XComponent> xSourceDoc(getShape(1), uno::UNO_QUERY);
xGraphicExporter->setSourceDocument(xSourceDoc);
// 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);
// 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);
}
// Without the fix in place, this test would have failed with // - Expected: Color: R:255 G:255 B:255 A:255 // - Actual : Color: R:190 G:227 B:211 A:0
CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, u"BackColor"_ustr));
// Without the fix in place, this test would have failed with // - Expected: 100 // - Actual : 150
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xPara, u"CharWeight"_ustr));
const css::uno::Any aNew(nDefTab * 2);
xTextDefaults->setPropertyValue(u"TabStopDistance"_ustr, aNew); // it may become slightly different because of conversions, so get the actual value const css::uno::Any aNewCorrected = xTextDefaults->getPropertyValue(u"TabStopDistance"_ustr);
CPPUNIT_ASSERT_DOUBLES_EQUAL(nDefTab * 2, aNewCorrected.get<sal_Int32>(), 1);
// Paste special as RTF constauto aPropertyValues = comphelper::InitPropertySequence(
{ { "SelectedFormat",
css::uno::Any(static_cast<sal_uInt32>(SotClipboardFormatId::RTF)) } });
dispatchCommand(mxComponent, u".uno:ClipboardFormatItems"_ustr, aPropertyValues);
// Without the fix in place, this would fail with // equality assertion failed // - Expected: <Any: (long) 2501> // - Actual : <Any: (long) 1251> // i.e., pasting RTF would reset the modified default tab stop distance to hardcoded default
CPPUNIT_ASSERT_EQUAL(aNewCorrected, xTextDefaults->getPropertyValue(u"TabStopDistance"_ustr));
}
// Use loadFromDesktop instead of loadFromURL to avoid calling mxComponent->dispose() // Otherwise it fails with 'DeInitVCL: some top Windows are still alive'
mxComponent = loadFromDesktop(maTempFile.GetURL());
// tdf#109285: RemoveLeadingWhiteSpace from all numbered paragraphs
getParagraph(1, u"a"_ustr);
getParagraph(2, u"b"_ustr);
getParagraph(3, u"c"_ustr);
// Save it as DOCX & load it again
saveAndReload(u"Office Open XML Text"_ustr);
uno::Reference<container::XIndexAccess> xNumberingRules
= getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1),
u"NumberingRules"_ustr);
CPPUNIT_ASSERT(xNumberingRules->getCount());
uno::Sequence<beans::PropertyValue> aNumbering;
xNumberingRules->getByIndex(0) >>= aNumbering;
OUString sCharStyleName; for (constauto& prop : aNumbering)
{ if (prop.Name == "CharStyleName")
{
prop.Value >>= sCharStyleName; break;
}
}
CPPUNIT_ASSERT(!sCharStyleName.isEmpty());
}
xmlDocUniquePtr pLayout = parseLayoutDump(); // Without the fix in place, this test would have failed with // - Expected: 2 // - Actual : 4
assertXPath(pLayout, "/root/page[1]/body/section[2]/txt", 2);
}
xmlDocUniquePtr pLayout = parseLayoutDump(); // Without the fix in place, there would be just the first index entry
assertXPath(pLayout, "/root/page[1]/body/txt[2]/anchored/fly/section/txt[1]/SwParaPortion/" "SwLineLayout[1]/SwLinePortion[1]", "portion", u"sub one");
assertXPath(pLayout, "/root/page[1]/body/txt[2]/anchored/fly/section/txt[2]/SwParaPortion/" "SwLineLayout[1]/SwLinePortion[1]", "portion", u"sub two");
assertXPath(pLayout, "/root/page[1]/body/txt[2]/anchored/fly/section/txt[3]/SwParaPortion/" "SwLineLayout[1]/SwLinePortion[1]", "portion", u"sub three");
// Without the fix in place, there would be just the first index entry
assertXPath(pLayout, "/root/page[1]/body/txt[6]/anchored/fly/section/txt[1]/SwParaPortion/" "SwLineLayout[1]/SwLinePortion[1]", "portion", u"another sub one");
assertXPath(pLayout, "/root/page[1]/body/txt[6]/anchored/fly/section/txt[2]/SwParaPortion/" "SwLineLayout[1]/SwLinePortion[1]", "portion", u"another sub two");
assertXPath(pLayout, "/root/page[1]/body/txt[6]/anchored/fly/section/txt[3]/SwParaPortion/" "SwLineLayout[1]/SwLinePortion[1]", "portion", u"another sub three");
}
for (int i = 1; i <= 3; i += 2)
{ const OUString frameStyleName
= getXPath(pXmlDoc, "/office:document-content/office:body/office:text/" "text:user-index[@text:name='User-Defined1']/text:index-body/text:p["
+ OString::number(i) + "]", "style-name"); const OUString tableStyleName
= getXPath(pXmlDoc, "/office:document-content/office:body/office:text/" "text:user-index[@text:name='User-Defined1']/text:index-body/text:p["
+ OString::number(i + 1) + "]", "style-name");
// Without the fix in place, the frame and table indentation would differ
CPPUNIT_ASSERT_EQUAL(frameStyleName, tableStyleName);
}
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf157129)
{ // Unit test for tdf#157129 // Test to see if cursor moves to the end after paste
// First document containing test data
createSwDoc("tdf157129.doc");
CPPUNIT_ASSERT_EQUAL(5, getParagraphs()); // Copy data from first document
dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
// Create a new document
createSwDoc();
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
// Paste data from first document
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
CPPUNIT_ASSERT_EQUAL(5, getParagraphs());
// Save cursor position after paste occurs
SwPosition aCursorPosPaste(*pWrtShell->GetCursor()->GetPoint());
// Move cursor position to the end
pWrtShell->SttEndDoc(false); //bStart = false
// Save cursor position at end
SwPosition aCursorPosEnd(*pWrtShell->GetCursor()->GetPoint());
// Assert the cursor position after paste is at the end // Without the test in place, the cursor position is at the beginning of the document // - Expected : SwPosition (node 18, offset 0) // - Actual : SwPosition (node 6, offset 0)
CPPUNIT_ASSERT_EQUAL(aCursorPosEnd, aCursorPosPaste);
}
// switch on "Outline Folding" mode
dispatchCommand(mxComponent, u".uno:ShowOutlineContentVisibilityButton"_ustr, {});
CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton());
// move the cursor to the beginning of the 3rd word in the 3rd paragraph, "tincidunt"
pWrtShell->FwdPara();
pWrtShell->FwdPara();
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 16, /*bBasicCall=*/false);
// select the word
dispatchCommand(mxComponent, u".uno:SelectWord"_ustr, {});
// check the word is select
SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
CPPUNIT_ASSERT_EQUAL(u"tincidunt"_ustr, pShellCursor->GetText());
// remember the cursor position for comparison
SwPosition aCursorPos(*pWrtShell->GetCursor()->GetPoint());
// without the fix in place, the cursor would have been set to the start of the outline node // - Expected: SwPosition (node 11, offset 25) // - Actual : SwPosition (node 9, offset 0)
CPPUNIT_ASSERT_EQUAL(aCursorPos, *pWrtShell->GetCursor()->GetPoint());
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf73483)
{ // Given a document with a first paragraph having a manually set page break with page style
createSwDoc("pageBreakWithPageStyle.fodt");
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
dispatchCommand(mxComponent, u".uno:ResetAttributes"_ustr,
{}); // Ctrl+M "Clear Direct Formatting" // Make sure that clearing direct formatting doesn't clear the page style
CPPUNIT_ASSERT_EQUAL(u"Right Page"_ustr, pWrtShell->GetCurPageStyle().toString());
// Make sure that the page break with page style survives ODF save-and-reload
saveAndReload(u"writer8"_ustr);
xmlDocUniquePtr pXml = parseExport(u"content.xml"_ustr);
CPPUNIT_ASSERT(pXml);
OUString para_style_name
= getXPath(pXml, "/office:document-content/office:body/office:text/text:p", "style-name"); // Without the fix in place, this would fail
CPPUNIT_ASSERT(!para_style_name.equalsIgnoreAsciiCase("Standard"));
OString para_style_path
= "/office:document-content/office:automatic-styles/style:style[@style:name='"
+ para_style_name.toUtf8() + "']";
assertXPath(pXml, para_style_path, "family", u"paragraph"); // Without the fix in place, the autostyle had no parent
assertXPath(pXml, para_style_path, "parent-style-name", u"Standard");
assertXPath(pXml, para_style_path, "master-page-name", u"Right_20_Page");
}
// Without the fix in place, it fails with: // - Expected: 1.1 // - Actual : 2
CPPUNIT_ASSERT_EQUAL(u"1.1"_ustr,
getProperty<OUString>(getParagraph(2), u"ListLabelString"_ustr).trim());
}
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
CPPUNIT_ASSERT(pWrtShell);
pWrtShell->FwdPara(); // Skip first paragraph
pWrtShell->EndOfSection(true); // Select everything to the end
SwDoc aClipboard;
pWrtShell->Copy(aClipboard); // This must not crash
pWrtShell->SelAll();
pWrtShell->Delete();
pWrtShell->Paste(aClipboard); // Replace everything with the copied stuff
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.50Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.