/* -*- 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/.
*/
namespace
{ class SwUiWriterTest9 : public SwModelTestBase
{ public:
SwUiWriterTest9()
: SwModelTestBase(u"/sw/qa/extras/uiwriter/data/"_ustr)
{
}
};
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf158785)
{ // given a document with a hyperlink surrounded by N-dashes (–www.dordt.edu–)
createSwDoc("tdf158785_hyperlink.fodt");
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
CPPUNIT_ASSERT(pWrtShell);
// go to the end of the hyperlink
pWrtShell->SttEndDoc(/*bStart=*/false);
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false); // get last point that will be part of the hyperlink (current position 1pt wide).
Point aLogicL(pWrtShell->GetCharRect().Center());
Point aLogicR(aLogicL);
// sanity check - we really are right by the hyperlink
aLogicL.AdjustX(-1);
SwContentAtPos aContentAtPos(IsAttrAtPos::InetAttr);
pWrtShell->GetContentAtPos(aLogicL, aContentAtPos);
CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::InetAttr, aContentAtPos.eContentAtPos);
// The test: the position of the N-dash should not indicate hyperlink properties // cursor pos would NOT be considered part of the hyperlink, but increase for good measure...
aLogicR.AdjustX(1);
pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
/* * tdf#111969: the beginning of the hyperlink should allow the right-click menu to remove it
*/ // move cursor (with no selection) to the start of the hyperlink - after the N-dash
pWrtShell->SttEndDoc(/*bStart=*/true);
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
aLogicL = pWrtShell->GetCharRect().Center();
aLogicR = aLogicL;
// sanity check - we really are right in front of the hyperlink
aLogicL.AdjustX(-1);
aContentAtPos = IsAttrAtPos::InetAttr;
pWrtShell->GetContentAtPos(aLogicL, aContentAtPos);
CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
aLogicR.AdjustX(1);
aContentAtPos = IsAttrAtPos::InetAttr;
pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::InetAttr, aContentAtPos.eContentAtPos);
// Remove the hyperlink
dispatchCommand(mxComponent, u".uno:RemoveHyperlink"_ustr, {});
// The test: was the hyperlink actually removed?
aContentAtPos = IsAttrAtPos::InetAttr;
pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
}
CPPUNIT_ASSERT(pWrtShell->IsCursorInFootnote()); // problem was that this was 29 with an extra text node in the footnote
CPPUNIT_ASSERT_EQUAL(SwNodeOffset(28), pDoc->GetNodes().Count());
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf111969)
{ // given a document with a field surrounded by N-dashes (–date–)
createSwDoc("tdf111969_field.fodt");
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
CPPUNIT_ASSERT(pWrtShell);
// go to the end of the field
pWrtShell->SttEndDoc(/*bStart=*/false);
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false); // get last point that will be part of the field (current position 1pt wide).
Point aLogicL(pWrtShell->GetCharRect().Center());
Point aLogicR(aLogicL);
// sanity check - we really are at the right edge of the field
aLogicR.AdjustX(1);
SwContentAtPos aContentAtPos(IsAttrAtPos::Field);
pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
aLogicL.AdjustX(-1);
aContentAtPos = IsAttrAtPos::Field;
pWrtShell->GetContentAtPos(aLogicL, aContentAtPos);
CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::Field, aContentAtPos.eContentAtPos);
// the test: simulate a right-click of a mouse which sets the cursor and then acts on that pos.
pWrtShell->SwCursorShell::SetCursor(aLogicL, false, /*Block=*/false, /*FieldInfo=*/true);
CPPUNIT_ASSERT(pWrtShell->GetCurField(true));
/* * An edge case at the start of a field - don't start the field menu on the first N-dash
*/ // go to the start of the field
pWrtShell->SttEndDoc(/*bStart=*/true);
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false); // get first point that will be part of the field (current position 1pt wide).
aLogicL = pWrtShell->GetCharRect().Center();
aLogicR = aLogicL;
// sanity check - we really are at the left edge of the field
aLogicR.AdjustX(1);
aContentAtPos = IsAttrAtPos::Field;
pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::Field, aContentAtPos.eContentAtPos);
aLogicL.AdjustX(-1);
aContentAtPos = IsAttrAtPos::Field;
pWrtShell->GetContentAtPos(aLogicL, aContentAtPos);
CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
// the test: simulate a right-click of a mouse (at the end-edge of the N-dash) // which sets the cursor and then acts on that pos.
pWrtShell->SwCursorShell::SetCursor(aLogicL, false, /*Block=*/false, /*FieldInfo=*/true);
CPPUNIT_ASSERT(!pWrtShell->GetCurField(true));
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf111969B)
{ // given a document with a field surrounded by two N-dashes (––date––)
createSwDoc("tdf111969_fieldB.fodt");
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
CPPUNIT_ASSERT(pWrtShell);
// go to the start of the field
pWrtShell->SttEndDoc(/*bStart=*/true);
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false); // get first point that will be part of the field (current position 1pt wide).
Point aLogicL(pWrtShell->GetCharRect().Center());
Point aLogicR(aLogicL);
// sanity check - we really are at the left edge of the field
aLogicR.AdjustX(1);
SwContentAtPos aContentAtPos(IsAttrAtPos::Field);
pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::Field, aContentAtPos.eContentAtPos);
aLogicL.AdjustX(-1);
aContentAtPos = IsAttrAtPos::Field;
pWrtShell->GetContentAtPos(aLogicL, aContentAtPos);
CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
// the test: simulate a right-click of a mouse (at the end-edge of the second N-dash) // which sets the cursor and then acts on that pos.
pWrtShell->SwCursorShell::SetCursor(aLogicL, false, /*Block=*/false, /*FieldInfo=*/true);
CPPUNIT_ASSERT(!pWrtShell->GetCurField(true));
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159049)
{ // The document contains a shape which has a text with a line break. When copying the text to // clipboard the line break was missing in the RTF flavor of the clipboard.
createSwDoc("tdf159049_LineBreakRTFClipboard.fodt");
CPPUNIT_ASSERT_EQUAL(1, getShapes());
selectShape(1);
// Bring shape into text edit mode
SwXTextDocument* pTextDoc = getSwTextDoc();
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RETURN);
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_RETURN);
Scheduler::ProcessEventsToIdle(); // Copy text
dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
// Paste special as RTF
uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
{ { "SelectedFormat", uno::Any(static_cast<sal_uInt32>(SotClipboardFormatId::RTF)) } }));
dispatchCommand(mxComponent, u".uno:ClipboardFormatItems"_ustr, aArgs); // Without fix Actual was "Abreakhere", the line break \n was missing.
CPPUNIT_ASSERT_EQUAL(u"Abreak\nhere"_ustr, getParagraph(1)->getString());
}
// Paste special as RTF
uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
{ { u"SelectedFormat"_ustr,
uno::Any(static_cast<sal_uInt32>(SotClipboardFormatId::RTF)) } }));
dispatchCommand(mxComponent, u".uno:ClipboardFormatItems"_ustr, aArgs);
auto xLastPara = getParagraph(3);
CPPUNIT_ASSERT_EQUAL(u"dolor"_ustr, xLastPara->getString()); // Without the fix in place, the last paragraph would loose its settings. ListId would be empty.
CPPUNIT_ASSERT(!getProperty<OUString>(xLastPara, u"ListId"_ustr).isEmpty());
}
auto xModel(mxComponent.queryThrow<frame::XModel>()); auto xTextViewCursorSupplier(
xModel->getCurrentController().queryThrow<text::XTextViewCursorSupplier>()); auto xCursor(xTextViewCursorSupplier->getViewCursor().queryThrow<text::XPageCursor>());
// Make sure that the page style is set correctly
xCursor->jumpToFirstPage();
CPPUNIT_ASSERT_EQUAL(u"Landscape"_ustr, getProperty<OUString>(xCursor, u"PageStyleName"_ustr));
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159565)
{ // Given a document with a hidden section in the beginning, additionally containing a frame
createSwDoc("FrameInHiddenSection.fodt");
// Check that the selection covers the whole visible text auto xModel(mxComponent.queryThrow<css::frame::XModel>()); auto xSelSupplier(xModel->getCurrentController().queryThrow<css::view::XSelectionSupplier>()); auto xSelections(xSelSupplier->getSelection().queryThrow<css::container::XIndexAccess>());
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSelections->getCount()); auto xSelection(xSelections->getByIndex(0).queryThrow<css::text::XTextRange>());
// Without the fix, this would fail - there was no selection
CPPUNIT_ASSERT_EQUAL(u"" SAL_NEWLINE_STRING SAL_NEWLINE_STRING "ipsum"_ustr,
xSelection->getString());
}
// Add a bookmark at the very end
IDocumentMarkAccess& rIDMA(*pDoc->getIDocumentMarkAccess());
rIDMA.makeMark(*pWrtShell->GetCursor(), SwMarkName(u"Mark"_ustr),
IDocumentMarkAccess::MarkType::BOOKMARK, sw::mark::InsertMode::New);
// Get coordinates of the end point in the document
SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
SwFrame* pPage = pLayout->Lower();
SwFrame* pBody = pPage->GetLower();
SwFrame* pLastPara = pBody->GetLower()->GetNext()->GetNext()->GetNext()->GetNext()->GetNext();
Point ptTo = pLastPara->getFrameArea().BottomRight();
pWrtShell->SelAll();
// Drag-n-drop to its own end
rtl::Reference<SwTransferable> xTransfer = new SwTransferable(*pWrtShell); // Without the fix, this would crash: either in CopyFlyInFlyImpl (tdf#159813): // Assertion failed: !pCopiedPaM || pCopiedPaM->End()->GetNode() == rRg.aEnd.GetNode() // or in BigPtrArray::operator[] (tdf#159816): // Assertion failed: idx < m_nSize
xTransfer->PrivateDrop(*pWrtShell, ptTo, /*bMove=*/true, /*bXSelection=*/true);
}
// Simulate a keyboard shortcut to SID_ATTR_CHAR_COLOR2 (which must use the shared button color)
dispatchCommand(mxComponent, u".uno:FontColor"_ustr, {});
pWrtShell->Insert(u"New World!"_ustr);
const uno::Reference<text::XTextRange> xRun = getRun(getParagraph(1, "New World!"), 1); // (This test assumes that nothing in the unit tests has modified the app's recent font color) // COL_DEFAULT_FONT is the default red color for the fontColor button on the toolbar.
CPPUNIT_ASSERT_EQUAL(COL_DEFAULT_FONT, getProperty<Color>(xRun, u"CharColor"_ustr));
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf139631)
{ // Unit test for tdf#139631 // Test to see if preceding space is cut when cutting a word with track changes (redline) on
createSwDoc();
SwDoc* pDoc = getSwDoc();
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
pWrtShell->Insert(u"New World!\""_ustr); // Assert that the string, New World!", is inserted correctly into the document
CPPUNIT_ASSERT_EQUAL(u"New World!\""_ustr, getParagraph(1)->getString());
pWrtShell->Left(SwCursorSkipMode::Chars, false, 2, false); // Select and cut "World" from string
pWrtShell->Left(SwCursorSkipMode::Chars, true, 5, false);
dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
pXmlDoc = parseLayoutDump(); // Verifies that the leading space before "World" was also cut
assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion", "portion", u"New!\"");
pWrtShell->Left(SwCursorSkipMode::Chars, false, 1, false); // Select and cut "World" from string
pWrtShell->Left(SwCursorSkipMode::Chars, true, 5, false);
dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
pXmlDoc = parseLayoutDump(); // Without the test in place, the leading space before "World" is not also cut. // Expected: New." // Actual: New ."
assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion", "portion", u"New.\"");
}
// Insert some text to work with
uno::Sequence<beans::PropertyValue> aArgsInsert(
comphelper::InitPropertySequence({ { "Text", uno::Any(u"abcd"_ustr) } }));
dispatchCommand(mxComponent, u".uno:InsertText"_ustr, aArgsInsert);
uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"abcd"_ustr, xTextDocument->getText()->getString());
// Successfully enclose the text; afterwards the selection should exist with the new // enclosed text
dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
SwXTextDocument* pTextDoc = getSwTextDoc();
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '(', 0);
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT_EQUAL(u"(abcd)"_ustr, xTextDocument->getText()->getString());
// Disable the setting and check that enclosing doesn't happen anymore const_cast<SwViewOption*>(pVwOpt)->SetEncloseWithCharactersOn(false);
CPPUNIT_ASSERT(!pVwOpt->IsEncloseWithCharactersOn());
// Given a document with several paragraphs, and a formula object
createSwDoc("text-with-formula.fodt");
CPPUNIT_ASSERT_EQUAL(3, getParagraphs());
SwXTextDocument* pTextDoc = getSwTextDoc(); auto& rObjectContainer = pTextDoc->GetObjectShell()->GetEmbeddedObjectContainer();
CPPUNIT_ASSERT(rObjectContainer.HasEmbeddedObjects()); auto xMathObject = rObjectContainer.GetEmbeddedObject(rObjectContainer.GetObjectNames()[0]);
CPPUNIT_ASSERT(xMathObject);
auto xSelSupplier = pTextDoc->getCurrentController().queryThrow<view::XSelectionSupplier>(); auto xCursor = pTextDoc->getText()->createTextCursor(); // 1. Select almost whole text, except the first and the last characters (to test the stability // of the selection boundaries) - meaning that the selection spans across three paragraphs:
xCursor->gotoRange(pTextDoc->getText()->getStart(), false);
xCursor->goRight(1, false);
xCursor->gotoRange(pTextDoc->getText()->getEnd(), true);
xCursor->goLeft(1, true);
xSelSupplier->select(css::uno::Any(xCursor));
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '(', 0);
Scheduler::ProcessEventsToIdle(); // The formula must not be removed from the document
CPPUNIT_ASSERT(rObjectContainer.HasEmbeddedObject(xMathObject));
auto xSelections = xSelSupplier->getSelection().queryThrow<css::container::XIndexAccess>();
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSelections->getCount()); auto xSelection = xSelections->getByIndex(0).queryThrow<css::text::XTextRange>(); // Check that selection includes parentheses
CPPUNIT_ASSERT_EQUAL(u"(aragraph one" SAL_NEWLINE_STRING "Paragraph two: " SAL_NEWLINE_STRING "Paragraph thre)"_ustr,
xSelection->getString()); // Check that the selection includes the formula auto xContentEnumAccess = xSelection.queryThrow<css::container::XContentEnumerationAccess>(); auto xContentEnum
= xContentEnumAccess->createContentEnumeration(u"com.sun.star.text.TextContent"_ustr);
CPPUNIT_ASSERT(xContentEnum->hasMoreElements());
// 2. Select part of the second paragraph, starting with the bold word, to the end (including // the formula), to test that the added characters assume the formatting of selection: auto xPara2 = getParagraph(2);
xCursor->gotoRange(xPara2->getStart(), false);
xCursor->goRight(10, false); // to start of "two", which is bold
xCursor->gotoRange(xPara2->getEnd(), true);
CPPUNIT_ASSERT_EQUAL(u"two: "_ustr, xCursor->getString());
xContentEnumAccess.set(xCursor, css::uno::UNO_QUERY_THROW);
xContentEnum
= xContentEnumAccess->createContentEnumeration(u"com.sun.star.text.TextContent"_ustr);
CPPUNIT_ASSERT(xContentEnum->hasMoreElements()); // The selection contains the formula
xSelSupplier->select(css::uno::Any(xCursor));
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '[', 0);
Scheduler::ProcessEventsToIdle(); // The formula must not be removed from the document
CPPUNIT_ASSERT(rObjectContainer.HasEmbeddedObject(xMathObject));
// The paragraph now must consist of five runs: first, the non-bold "Paragraph "; // then bold "[two"; then non-bold ": "; then the formula; and then non-bold "]": auto xRun = getRun(xPara2, 1, u"Paragraph "_ustr);
CPPUNIT_ASSERT_EQUAL(100.0f, getProperty<float>(xRun, u"CharWeight"_ustr));
xRun = getRun(xPara2, 2, u"[two"_ustr);
CPPUNIT_ASSERT_EQUAL(150.0f, getProperty<float>(xRun, u"CharWeight"_ustr));
xRun = getRun(xPara2, 3, u": "_ustr);
CPPUNIT_ASSERT_EQUAL(100.0f, getProperty<float>(xRun, u"CharWeight"_ustr));
xRun = getRun(xPara2, 4, u""_ustr); // Check that the run includes the formula
xContentEnumAccess.set(xRun, css::uno::UNO_QUERY_THROW);
xContentEnum
= xContentEnumAccess->createContentEnumeration(u"com.sun.star.text.TextContent"_ustr);
CPPUNIT_ASSERT(xContentEnum->hasMoreElements()); // The selection contains the formula
xRun = getRun(xPara2, 5, u"]"_ustr);
CPPUNIT_ASSERT_EQUAL(100.0f, getProperty<float>(xRun, u"CharWeight"_ustr));
}
// Given a document with a single paragraph, having a formula object
createSwDoc("text-with-formula-one-paragraph.fodt");
dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
SwDoc* pDoc = getSwDoc();
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
pDoc->getIDocumentContentOperations().ReplaceRange(*pWrtShell->GetCursor(), "", false);
Scheduler::ProcessEventsToIdle(); // This must not crash!
}
// select (at least parts) of the first two paragraphs
pWrtShell->Down(/*bSelect=*/true, /*nCount=*/1, /*bBasicCall=*/true);
// on the selection, simulate pressing the toolbar button to toggle OFF numbering
dispatchCommand(mxComponent, u".uno:DefaultNumbering"_ustr, {});
// the selected paragraphs should definitely have the list label removed
CPPUNIT_ASSERT_EQUAL(u""_ustr, getProperty<OUString>(xPara1, u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u""_ustr, getProperty<OUString>(xPara2, u"ListLabelString"_ustr)); // the third paragraph must retain the existing numbering format
CPPUNIT_ASSERT_EQUAL(u"A."_ustr, getProperty<OUString>(xPara3, u"ListLabelString"_ustr));
// on the selection, simulate pressing the toolbar button to toggle ON numbering again
dispatchCommand(mxComponent, u".uno:DefaultNumbering"_ustr, {});
// the outline numbering format must be re-applied to the first two paragraphs
CPPUNIT_ASSERT_EQUAL(u"A."_ustr, getProperty<OUString>(xPara1, u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u"B."_ustr, getProperty<OUString>(xPara2, u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u"C."_ustr, getProperty<OUString>(xPara3, u"ListLabelString"_ustr));
// on the selection, simulate a right click - list - No list
dispatchCommand(mxComponent, u".uno:RemoveBullets"_ustr, {});
// the selected paragraphs should definitely have the list label removed
CPPUNIT_ASSERT_EQUAL(u""_ustr, getProperty<OUString>(xPara1, u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u""_ustr, getProperty<OUString>(xPara2, u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(u"A."_ustr, getProperty<OUString>(xPara3, u"ListLabelString"_ustr));
}
// force the AppName to enable DDE, it is not there for test runs
Application::SetAppName(u"soffice"_ustr);
// temp copy for the file that will be used as a reference for DDE link // this file includes a section named "Section1" with text inside
createTempCopy(u"tdf158375_dde_reference.fodt");
// create a section with DDE link
uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xTextSectionProps(
xFactory->createInstance(u"com.sun.star.text.TextSection"_ustr), uno::UNO_QUERY);
// make sure there's no text in the section after UpdateAllLinks, since // DisableActiveContent disables DDE links.
CPPUNIT_ASSERT_EQUAL(u""_ustr, xSection->getAnchor()->getString());
}
// Enable LOK mode, otherwise OCommonEmbeddedObject::SwitchStateTo_Impl() will throw when it // finds out that the test runs headless.
comphelper::LibreOfficeKit::setActive();
// Load a document with a Draw doc in it.
createSwDoc("ole-save-while-edit.odt");
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
selectShape(1);
// attempt to edit the OLE object.
pWrtShell->LaunchOLEObj();
// it shouldn't switch because the current configuration // (DisableActiveContent) prohibits OLE objects changing to states other // then LOADED auto xShape = getShape(1);
uno::Reference<document::XEmbeddedObjectSupplier2> xEmbedSupplier(xShape, uno::UNO_QUERY); auto xEmbeddedObj = xEmbedSupplier->getExtendedControlOverEmbeddedObject();
CPPUNIT_ASSERT_EQUAL(embed::EmbedStates::LOADED, xEmbeddedObj->getCurrentState());
// Dispose the document while LOK is still active to avoid leaks.
mxComponent->dispose();
mxComponent.clear();
comphelper::LibreOfficeKit::setActive(false);
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf146190)
{ // Given a document with a number rule at the start of a paragraph and two drawing objects:
createSwDoc("tdf146190.odt");
SwDocShell* pDocShell = getSwDocShell();
SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
// Assert the current cursor position has a number rule and is at the start of a paragraph:
pWrtShell->SttEndDoc(/*bStt=*/true);
CPPUNIT_ASSERT(pWrtShell->GetNumRuleAtCurrCursorPos());
CPPUNIT_ASSERT(pWrtShell->IsSttOfPara());
// Then go to "Shape 1" drawing object using the GotoDrawingObject function:
pWrtShell->GotoDrawingObject(u"Shape 1");
CPPUNIT_ASSERT_EQUAL(u"Shape 1"_ustr, rMrkList.GetMark(0)->GetMarkedSdrObj()->GetName());
// Move to the next drawing object by Tab key press:
SwXTextDocument* pTextDoc = getSwTextDoc();
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
Scheduler::ProcessEventsToIdle(); // Without the fix in place, this test would have failed with: // equality assertion failed // - Expected: Shape 2 // - Actual : Shape 1 // i.e. Tab did not move to the next drawing object
CPPUNIT_ASSERT_EQUAL(u"Shape 2"_ustr, rMrkList.GetMark(0)->GetMarkedSdrObj()->GetName());
// Tab key press should now select 'Shape 1':
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT_EQUAL(u"Shape 1"_ustr, rMrkList.GetMark(0)->GetMarkedSdrObj()->GetName());
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf160898)
{ // Given a document with a 1-cell table in another 1-cell table:
createSwDoc("table-in-table.fodt");
SwDocShell* pDocShell = getSwDocShell();
SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
// Move to the normally hidden paragraph inside the outer table cell, following the inner table
pWrtShell->Down(false, 2); // Without the fix, this would crash:
pWrtShell->SelAll();
}
// Disable map mode, so that it's possible to send mouse event coordinates // directly in twips.
SwEditWin& rEditWin = getSwDocShell()->GetView()->GetEditWin();
rEditWin.EnableMapMode(false);
// Cursor is already on cell A1
uno::Sequence aArgs{ comphelper::makePropertyValue(u"PersistentCopy"_ustr, uno::Any(false)) };
dispatchCommand(mxComponent, u".uno:FormatPaintbrush"_ustr, aArgs);
// Disable map mode, so that it's possible to send mouse event coordinates // directly in twips.
SwEditWin& rEditWin = getSwDocShell()->GetView()->GetEditWin();
rEditWin.EnableMapMode(false);
// Without the fix in place, this test would have failed with // - Expected: € 100,00 // - Actual : 100
CPPUNIT_ASSERT_EQUAL(u"€ 100,00"_ustr, xCellA2->getString());
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf161172)
{ // Given a paragraph manually made a member of a list:
createSwDoc("tdf161172.fodt"); auto para = getParagraph(1);
// Check initial state: the first paragraph has "No_list" para style, "Num_1" numbering style, // numbering level 0, and "Num1_lvl1_1" numbering label.
CPPUNIT_ASSERT_EQUAL(u"No_list"_ustr, getProperty<OUString>(para, u"ParaStyleName"_ustr));
CPPUNIT_ASSERT_EQUAL(u"Num_1"_ustr, getProperty<OUString>(para, u"NumberingStyleName"_ustr));
CPPUNIT_ASSERT_EQUAL(u"Num1_lvl1_1"_ustr, getProperty<OUString>(para, u"ListLabelString"_ustr));
CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(para, u"NumberingLevel"_ustr));
// Assign "Num_1_lvl2" paragraph style to the first paragraph. The style is associated with // "Num_1" numbering style, level 1.
dispatchCommand(mxComponent, u".uno:StyleApply"_ustr,
{ comphelper::makePropertyValue(u"FamilyName"_ustr, u"ParagraphStyles"_ustr),
comphelper::makePropertyValue(u"Style"_ustr, u"Num_1_lvl2"_ustr) });
// Check that the numbering properties got correctly restored
CPPUNIT_ASSERT_EQUAL(u"No_list"_ustr, getProperty<OUString>(para, u"ParaStyleName"_ustr));
CPPUNIT_ASSERT_EQUAL(u"Num_1"_ustr, getProperty<OUString>(para, u"NumberingStyleName"_ustr)); // Without the fix, this would fail with // - Expected: Num1_lvl1_1 // - Actual : Num1_lvl2_1
CPPUNIT_ASSERT_EQUAL(u"Num1_lvl1_1"_ustr, getProperty<OUString>(para, u"ListLabelString"_ustr)); // Without the fix, this would fail with // - Expected: 0 // - Actual : 1
CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(para, u"NumberingLevel"_ustr));
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf144752)
{ // Undoing/redoing a replacement must select the new text
createSwDoc();
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
CPPUNIT_ASSERT(pWrtShell);
emulateTyping(u"Some Text");
CPPUNIT_ASSERT(!pWrtShell->HasSelection()); // Select "Text", and replace with "Word"
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect*/ true, 4, /*bBasicCall*/ false);
pWrtShell->Replace(u"Word"_ustr, false);
pWrtShell->EndOfSection();
CPPUNIT_ASSERT(!pWrtShell->HasSelection());
// Undo and check, that the "Text" is selected
dispatchCommand(mxComponent, u".uno:Undo"_ustr, {}); // Without the fix, this would fail
CPPUNIT_ASSERT(pWrtShell->HasSelection());
CPPUNIT_ASSERT_EQUAL(u"Text"_ustr, pWrtShell->GetSelText());
// Redo and check, that the "Word" is selected
dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
CPPUNIT_ASSERT(pWrtShell->HasSelection());
CPPUNIT_ASSERT_EQUAL(u"Word"_ustr, pWrtShell->GetSelText());
}
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL,
getProperty<float>(getRun(getParagraph(1), 1), u"CharWeight"_ustr));
CPPUNIT_ASSERT_THROW(getRun(getParagraph(2), 2), css::container::NoSuchElementException); //last runs are not changed because the selection ends at the beginning of that paragraph
CPPUNIT_ASSERT_EQUAL(short(1),
getProperty<short>(getRun(getParagraph(3), 2), u"CharUnderline"_ustr));
}
for (int i = 0; i < 14; i++)
xParaCursor->gotoNextParagraph(false);
xParaCursor->gotoEndOfParagraph(true);
xSelSupplier->select(uno::Any(xParaCursor));
xParaCursor = uno::Reference<text::XParagraphCursor>(xText->createTextCursor(), uno::UNO_QUERY); for (int i = 0; i < 3; i++)
xParaCursor->gotoNextParagraph(false);
xParaCursor->gotoEndOfParagraph(true);
CPPUNIT_ASSERT_EQUAL(u"1."_ustr, getProperty<OUString>(xParaCursor, u"ListLabelString"_ustr));
xSelSupplier->select(uno::Any(xParaCursor));
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
CPPUNIT_ASSERT_EQUAL(u"A."_ustr, getProperty<OUString>(xParaCursor, u"ListLabelString"_ustr));
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf163340_2)
{ //selects and copies a single paragraph with a list (bullets) //and pastes it into an empty paragraph with a different list (numbers) //checks that the resulting paragraph keeps that different list
createSwDoc("tdf163340_2.odt");
uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
uno::Reference<text::XText> xText = xTextDocument->getText();
uno::Reference<view::XSelectionSupplier> xSelSupplier(xModel->getCurrentController(),
uno::UNO_QUERY_THROW);
uno::Reference<text::XParagraphCursor> xParaCursor(xTextDocument->getText()->createTextCursor(),
uno::UNO_QUERY);
for (int i = 0; i < 2; i++)
xParaCursor->gotoNextParagraph(false);
xParaCursor->gotoEndOfParagraph(true);
xSelSupplier->select(uno::Any(xParaCursor));
xParaCursor = uno::Reference<text::XParagraphCursor>(xText->createTextCursor(), uno::UNO_QUERY); for (int i = 0; i < 10; i++)
xParaCursor->gotoNextParagraph(false);
xParaCursor->gotoEndOfParagraph(true);
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
CPPUNIT_ASSERT_EQUAL(u"5."_ustr, getProperty<OUString>(xParaCursor, u"ListLabelString"_ustr));
}
// Without the fix in place, this test would have crashed here
CPPUNIT_ASSERT(pWrtShell->IsCursorInFootnote());
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf162195)
{ // Given a document, which has some index entries in a hidden section
createSwDoc("IndexElementsInHiddenSections.fodt");
auto xIndexSupplier(mxComponent.queryThrow<css::text::XDocumentIndexesSupplier>()); auto xIndexes = xIndexSupplier->getDocumentIndexes();
CPPUNIT_ASSERT(xIndexes);
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexes->getCount()); // A ToC and a table index
auto xToC(xIndexes->getByIndex(0).queryThrow<css::text::XDocumentIndex>());
xToC->update(); // Without the fix, all the elements from the hidden section appeared in the index
CPPUNIT_ASSERT_EQUAL(u"Table of Contents" SAL_NEWLINE_STRING "Section Visible\t1"_ustr,
xToC->getAnchor()->getString());
auto xTables(xIndexes->getByIndex(1).queryThrow<css::text::XDocumentIndex>());
xTables->update(); // Without the fix, all the elements from the hidden section appeared in the index
CPPUNIT_ASSERT_EQUAL(u"Index of Tables" SAL_NEWLINE_STRING "Table1\t1"_ustr,
xTables->getAnchor()->getString());
// Show the hidden section auto xTextSectionsSupplier = mxComponent.queryThrow<css::text::XTextSectionsSupplier>(); auto xSections = xTextSectionsSupplier->getTextSections();
CPPUNIT_ASSERT(xSections); auto xSection
= xSections->getByName(u"Section Hidden"_ustr).queryThrow<css::beans::XPropertySet>();
xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(true));
// Prior to editing, there should be no kashida auto stBeforeKashida = pSI->GetKashidaPositions();
CPPUNIT_ASSERT_EQUAL(size_t(0), stBeforeKashida.size());
// Insert text at the beginning of the document
pWrtShell->Insert(u"A"_ustr);
// After editing, there should still be no room for kashida // Without the fix, this will be non-zero auto stAfterKashida = pSI->GetKashidaPositions();
CPPUNIT_ASSERT_EQUAL(size_t(0), stAfterKashida.size());
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf71583)
{ //create a document, multiple pages, some restart page counting // insert page count in section fields and check the calculated // values
auto insertParagraphAndBreak = [](sal_Int32& nParagraph, SwWrtShell& rWrtSh,
uno::Reference<lang::XComponent> xComponent, const sal_uInt16 nPages) { for (sal_uInt16 nPage = 0; nPage < nPages; ++nPage)
{
rWrtSh.Insert(u"Paragraph "_ustr);
rWrtSh.Insert(OUString::number(nParagraph));
++nParagraph; auto xModel(xComponent.queryThrow<frame::XModel>()); auto xFactory(xComponent.queryThrow<lang::XMultiServiceFactory>()); auto xTextViewCursorSupplier(
xModel->getCurrentController().queryThrow<text::XTextViewCursorSupplier>()); auto xTextRangeCursor(
xTextViewCursorSupplier->getViewCursor().queryThrow<text::XTextRange>());
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.