Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / qa / extras / uiwriter / uiwriter.cxx
blob58ebbcde09ff48e5dd70800461b55101d0ba9ea4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
11 #include <com/sun/star/awt/FontWeight.hpp>
12 #include <com/sun/star/document/XDocumentInsertable.hpp>
13 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
14 #include <com/sun/star/i18n/TextConversionOption.hpp>
15 #include <swmodeltestbase.hxx>
16 #include <ndtxt.hxx>
17 #include <wrtsh.hxx>
18 #include <shellio.hxx>
19 #include <expfld.hxx>
20 #include <drawdoc.hxx>
21 #include <redline.hxx>
22 #include <fmtclds.hxx>
23 #include <dcontact.hxx>
24 #include <view.hxx>
25 #include <hhcwrp.hxx>
26 #include <swacorr.hxx>
27 #include <swmodule.hxx>
28 #include <modcfg.hxx>
29 #include <editeng/acorrcfg.hxx>
30 #include <unotools/streamwrap.hxx>
31 #include <unocrsrhelper.hxx>
32 #include <com/sun/star/text/VertOrientation.hpp>
33 #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
34 #include <com/sun/star/text/XTextTable.hpp>
35 #include <vcl/TypeSerializer.hxx>
37 #include <svx/svdpage.hxx>
38 #include <svx/svdview.hxx>
39 #include <svx/svxids.hrc>
41 #include <editeng/eeitem.hxx>
42 #include <editeng/scripttypeitem.hxx>
43 #include <editeng/wghtitem.hxx>
44 #include <IDocumentDrawModelAccess.hxx>
45 #include <IDocumentRedlineAccess.hxx>
46 #include <UndoManager.hxx>
47 #include <frmatr.hxx>
49 #include <com/sun/star/text/TextMarkupType.hpp>
50 #include <osl/file.hxx>
51 #include <comphelper/propertysequence.hxx>
52 #include <sfx2/viewfrm.hxx>
53 #include <sfx2/dispatch.hxx>
54 #include <vcl/scheduler.hxx>
55 #include <sfx2/watermarkitem.hxx>
56 #include <sfx2/docfile.hxx>
57 #include <fmthdft.hxx>
58 #include <iodetect.hxx>
59 #include <comphelper/processfactory.hxx>
60 #include <unotxdoc.hxx>
61 #include <swdtflvr.hxx>
62 #include <sortedobjs.hxx>
63 #include <rootfrm.hxx>
64 #include <txtfrm.hxx>
66 namespace
68 void lcl_selectCharacters(SwPaM& rPaM, sal_Int32 first, sal_Int32 end)
70 rPaM.GetPoint()->nContent.Assign(rPaM.GetPointContentNode(), first);
71 rPaM.SetMark();
72 rPaM.GetPoint()->nContent.Assign(rPaM.GetPointContentNode(), end);
74 } //namespace
76 class SwUiWriterTest : public SwModelTestBase
78 public:
79 SwUiWriterTest() :
80 SwModelTestBase("/sw/qa/extras/uiwriter/data/")
83 std::unique_ptr<SwTextBlocks> readDOCXAutotext(
84 std::u16string_view sFileName, bool bEmpty = false);
85 void testRedlineFrame(char const*const file);
88 std::unique_ptr<SwTextBlocks> SwUiWriterTest::readDOCXAutotext(std::u16string_view sFileName, bool bEmpty)
90 createTempCopy(sFileName);
92 SfxMedium aSrcMed(maTempFile.GetURL(), StreamMode::STD_READ);
93 createSwDoc();
94 SwDoc* pDoc = getSwDoc();
96 SwReader aReader(aSrcMed, maTempFile.GetURL(), pDoc);
97 Reader* pDOCXReader = SwReaderWriter::GetDOCXReader();
98 auto pGlossary = std::make_unique<SwTextBlocks>(maTempFile.GetURL());
100 CPPUNIT_ASSERT(pDOCXReader != nullptr);
101 CPPUNIT_ASSERT_EQUAL(!bEmpty, aReader.ReadGlossaries(*pDOCXReader, *pGlossary, false));
103 return pGlossary;
106 void SwUiWriterTest::testRedlineFrame(char const*const file)
108 createSwDoc(file);
109 SwDoc* pDoc = getSwDoc();
110 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
112 // there is exactly one frame
113 CPPUNIT_ASSERT_EQUAL(1, getShapes());
115 RedlineFlags nMode = pWrtShell->GetRedlineFlags();
116 CPPUNIT_ASSERT(nMode & RedlineFlags::ShowDelete);
118 // hide delete redlines
119 pWrtShell->SetRedlineFlags(nMode & ~RedlineFlags::ShowDelete);
121 // there is still exactly one frame
122 CPPUNIT_ASSERT_EQUAL(1, getShapes());
124 pWrtShell->SetRedlineFlags(nMode); // show again
126 // there is still exactly one frame
127 CPPUNIT_ASSERT_EQUAL(1, getShapes());
130 //Replacement tests
132 constexpr OUStringLiteral ORIGINAL_REPLACE_CONTENT(u"toto titi tutu");
133 constexpr OUStringLiteral EXPECTED_REPLACE_CONTENT(u"toto toto tutu");
135 // Chinese conversion tests
137 const sal_Unicode CHINESE_TRADITIONAL_CONTENT(0x9F8D);
138 const sal_Unicode CHINESE_SIMPLIFIED_CONTENT(0x9F99);
139 constexpr OUStringLiteral NON_CHINESE_CONTENT(u"Hippopotamus");
141 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testReplaceForward)
143 createSwDoc();
144 SwDoc* pDoc = getSwDoc();
146 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
148 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
149 SwPaM aPaM(aIdx);
151 pDoc->getIDocumentContentOperations().InsertString(aPaM, ORIGINAL_REPLACE_CONTENT);
153 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
154 lcl_selectCharacters(aPaM, 5, 9);
155 pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, "toto", false);
157 CPPUNIT_ASSERT_EQUAL(OUString(EXPECTED_REPLACE_CONTENT), pTextNode->GetText());
159 rUndoManager.Undo();
161 CPPUNIT_ASSERT_EQUAL(OUString(ORIGINAL_REPLACE_CONTENT), pTextNode->GetText());
165 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtCharStartOutside0)
167 testRedlineFrame("redlineFrame.fodt");
170 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtCharStartOutside)
172 testRedlineFrame("redlineFrame_at_char_start_outside.fodt");
175 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtCharStartInside)
177 testRedlineFrame("redlineFrame_at_char_start_inside.fodt");
180 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtParaStartOutside)
182 testRedlineFrame("redline_fly_duplication_at_para_start_outside.fodt");
185 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtParaEndInside)
187 testRedlineFrame("redline_fly_duplication_at_para_end_inside.fodt");
190 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtParaOneParagraph)
192 // test ALLFLYS flag: oddly enough it didn't fail as fodt but failed as odt...
193 testRedlineFrame("redline_fly_at_para_one_paragraph.odt");
196 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtPara2ndParagraph)
198 // lost via the buggy increment in Copy
199 testRedlineFrame("redline_fly_duplication_at_para_2nd_paragraph.fodt");
202 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testThreadedException)
204 SvFileStream aFileStream(createFileURL(u"threadedException.fodt"), StreamMode::READ);
206 //threaded reading only kicks in if there is sufficient buffer to make it worthwhile, so read
207 //from a SvFileStream to ensure that
208 bool bRes = TestImportFODT(aFileStream);
210 CPPUNIT_ASSERT(!bRes);
213 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf149595)
215 createSwDoc("demo91.fodt");
216 SwDoc* pDoc = getSwDoc();
218 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
220 // all 4 shapes are on the 2nd paragraph
221 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
222 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
223 CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
226 pWrtShell->Down(false);
227 pWrtShell->EndPara(/*bSelect=*/true);
228 dispatchCommand(mxComponent, ".uno:Cut", {});
230 // one shape is anchored in the middle, others at the start/end/at-para
231 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
232 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
233 CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
235 pWrtShell->Up(false);
236 dispatchCommand(mxComponent, ".uno:Paste", {});
238 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() != nullptr);
239 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs()->size());
240 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
241 CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
243 pWrtShell->Undo();
244 pWrtShell->Undo();
246 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
247 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
248 CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
251 // now try the same with redlining enabled - should be the same result
252 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
253 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
255 pWrtShell->Down(false);
256 pWrtShell->SttPara(/*bSelect=*/false);
257 pWrtShell->EndPara(/*bSelect=*/true);
258 dispatchCommand(mxComponent, ".uno:Cut", {});
260 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
261 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
262 // problem was that this deleted all at-char flys, even at the start/end
263 CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
265 pWrtShell->Up(false);
266 dispatchCommand(mxComponent, ".uno:Paste", {});
268 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() != nullptr);
269 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs()->size());
270 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
271 CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
273 pWrtShell->Undo();
274 pWrtShell->Undo();
276 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
277 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
278 CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
282 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf149548)
284 createSwDoc("forum-mso-en-13192-min.docx");
285 SwDoc* pDoc = getSwDoc();
287 for (SwRangeRedline const*const pRedline : pDoc->getIDocumentRedlineAccess().GetRedlineTable())
289 if (pRedline->GetType() == RedlineType::Delete)
291 int nLevel(0);
292 for (SwNodeIndex index = pRedline->Start()->nNode; index <= pRedline->End()->nNode; ++index)
294 switch (index.GetNode().GetNodeType())
296 case SwNodeType::Start:
297 case SwNodeType::Table:
298 case SwNodeType::Section:
299 ++nLevel;
300 break;
301 case SwNodeType::End:
302 CPPUNIT_ASSERT_MESSAGE("bad overlapping redline", nLevel != 0);
303 --nLevel;
304 break;
305 default:
306 break;
309 CPPUNIT_ASSERT_EQUAL_MESSAGE("bad overlapping redline", int(0), nLevel);
313 dispatchCommand(mxComponent, ".uno:SelectAll", {});
315 dispatchCommand(mxComponent, ".uno:Copy", {});
317 // this was a use-after-free on nodes deleted by Copy
318 dispatchCommand(mxComponent, ".uno:Paste", {});
321 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testBookmarkCopy)
323 createSwDoc();
324 SwDoc* pDoc = getSwDoc();
326 // add text and bookmark
327 IDocumentMarkAccess & rIDMA(*pDoc->getIDocumentMarkAccess());
328 IDocumentContentOperations & rIDCO(pDoc->getIDocumentContentOperations());
329 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
330 SwCursor aPaM(SwPosition(aIdx), nullptr);
331 rIDCO.InsertString(aPaM, "foo");
332 rIDCO.SplitNode(*aPaM.GetPoint(), false);
333 rIDCO.InsertString(aPaM, "bar");
334 aPaM.SetMark();
335 aPaM.MovePara(GoCurrPara, fnParaStart);
336 rIDMA.makeMark(aPaM, "Mark", IDocumentMarkAccess::MarkType::BOOKMARK,
337 ::sw::mark::InsertMode::New);
338 aPaM.Exchange();
339 aPaM.DeleteMark();
340 rIDCO.SplitNode(*aPaM.GetPoint(), false);
341 rIDCO.InsertString(aPaM, "baz");
343 // copy range
344 rIDCO.SplitNode(*aPaM.GetPoint(), false);
345 SwPosition target(*aPaM.GetPoint());
346 aPaM.Move(fnMoveBackward, GoInContent);
347 aPaM.SetMark();
348 aPaM.SttEndDoc(true/*start*/);
349 aPaM.Move(fnMoveForward, GoInContent); // partially select 1st para
351 rIDCO.CopyRange(aPaM, target, SwCopyFlags::CheckPosInFly);
353 // check bookmark was copied to correct position
354 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), rIDMA.getBookmarksCount());
355 for (auto it(rIDMA.getBookmarksBegin()); it != rIDMA.getBookmarksEnd(); ++it)
357 OUString markText(SwPaM((*it)->GetMarkPos(), (*it)->GetOtherMarkPos()).GetText());
358 CPPUNIT_ASSERT_EQUAL(OUString("bar"), markText);
361 // copy 2nd time, such that bCanMoveBack is false in CopyImpl
362 SwPaM aCopyPaM(*aPaM.GetMark(), *aPaM.GetPoint());
363 aPaM.SttEndDoc(true/*start*/);
364 rIDCO.SplitNode(*aPaM.GetPoint(), false);
365 aPaM.SttEndDoc(true/*start*/);
367 rIDCO.CopyRange(aCopyPaM, *aPaM.GetPoint(), SwCopyFlags::CheckPosInFly);
369 // check bookmark was copied to correct position
370 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), rIDMA.getBookmarksCount());
371 for (auto it(rIDMA.getBookmarksBegin()); it != rIDMA.getBookmarksEnd(); ++it)
373 OUString markText(SwPaM((*it)->GetMarkPos(), (*it)->GetOtherMarkPos()).GetText());
374 CPPUNIT_ASSERT_EQUAL(OUString("bar"), markText);
378 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFormulaNumberWithGroupSeparator)
380 createSwDoc("tdf125154.odt");
381 dispatchCommand(mxComponent, ".uno:UpdateAll", {});
382 SwDoc* pDoc = getSwDoc();
383 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
384 pWrtShell->SttEndDoc(true);
385 SwField const* pField;
387 pField = pWrtShell->GetCurField();
388 CPPUNIT_ASSERT_EQUAL(OUString("1000"), pField->GetFormula());
389 CPPUNIT_ASSERT_EQUAL(OUString("1.000"), pField->ExpandField(true, nullptr));
390 pWrtShell->GoNextCell();
391 CPPUNIT_ASSERT_EQUAL(OUString("10000"), pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
392 pWrtShell->GoNextCell();
393 pField = pWrtShell->GetCurField();
394 CPPUNIT_ASSERT_EQUAL(OUString("test"), pField->GetFormula());
395 CPPUNIT_ASSERT_EQUAL(OUString("1.000"), pField->ExpandField(true, nullptr));
396 pWrtShell->GoNextCell();
397 // the problem was that this was 0
398 CPPUNIT_ASSERT_EQUAL(OUString("10000"), pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
399 pWrtShell->Down(false);
400 pWrtShell->SttPara(false);
401 pField = pWrtShell->GetCurField();
402 CPPUNIT_ASSERT_EQUAL(OUString("1000*10%"), pField->GetFormula());
403 CPPUNIT_ASSERT_EQUAL(OUString("100"), pField->ExpandField(true, nullptr));
404 pWrtShell->Down(false);
405 pField = pWrtShell->GetCurField();
406 CPPUNIT_ASSERT_EQUAL(OUString("5.000*10%"), pField->GetFormula());
407 // the problem was that this was 0
408 CPPUNIT_ASSERT_EQUAL(OUString("500"), pField->ExpandField(true, nullptr));
409 pWrtShell->Down(false);
410 pField = pWrtShell->GetCurField();
411 CPPUNIT_ASSERT_EQUAL(OUString("5.000*10%"), pField->GetFormula());
412 // the problem was that this was
413 CPPUNIT_ASSERT_EQUAL(OUString("500"), pField->ExpandField(true, nullptr));
414 pWrtShell->Down(false);
415 pField = pWrtShell->GetCurField();
416 CPPUNIT_ASSERT_EQUAL(OUString("5000*10%"), pField->GetFormula());
417 CPPUNIT_ASSERT_EQUAL(OUString("500"), pField->ExpandField(true, nullptr));
418 pWrtShell->Down(false);
419 CPPUNIT_ASSERT_EQUAL(OUString(u"-100,00 €"), pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
420 pWrtShell->GoNextCell();
421 // tdf#42518 the problem was that this was 1.900,00 €
422 CPPUNIT_ASSERT_EQUAL(OUString("** Expression is faulty **"), pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
425 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testInsertFileInInputFieldException)
427 createSwDoc();
428 uno::Reference<text::XTextDocument> const xTextDoc(mxComponent, uno::UNO_QUERY);
429 uno::Reference<text::XText> const xBody(xTextDoc->getText());
430 uno::Reference<lang::XMultiServiceFactory> const xFactory(mxComponent, uno::UNO_QUERY);
431 uno::Reference<text::XTextCursor> const xCursor(xBody->createTextCursor());
432 uno::Reference<document::XDocumentInsertable> const xInsertable(xCursor, uno::UNO_QUERY);
433 uno::Reference<text::XTextContent> const xContent(
434 xFactory->createInstance("com.sun.star.text.textfield.Input"), uno::UNO_QUERY);
435 xBody->insertTextContent(xCursor, xContent, false);
436 xCursor->goLeft(1, false);
437 // try to insert some random file
438 // inserting even asserts in debug builds - document model goes invalid with input field split across 2 nodes
439 CPPUNIT_ASSERT_THROW(xInsertable->insertDocumentFromURL(createFileURL(u"fdo75110.odt"), {}), uno::RuntimeException);
442 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf67238)
444 //create a new writer document
445 createSwDoc();
446 SwDoc* pDoc = getSwDoc();
447 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
448 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
449 //insert a 3X3 table in the newly created document
450 SwInsertTableOptions TableOpt(SwInsertTableFlags::DefaultBorder, 0);
451 const SwTable& rTable = pWrtShell->InsertTable(TableOpt, 3, 3);
452 //checking for the rows and columns
453 uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
454 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getRows()->getCount());
455 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getColumns()->getCount());
456 //selecting the table
457 pWrtShell->StartOfSection();
458 pWrtShell->SelTable();
459 //making the table protected
460 pWrtShell->ProtectCells();
461 //checking each cell's protection, it should be protected
462 CPPUNIT_ASSERT(((rTable.GetTableBox("A1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
463 CPPUNIT_ASSERT(((rTable.GetTableBox("A2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
464 CPPUNIT_ASSERT(((rTable.GetTableBox("A3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
465 CPPUNIT_ASSERT(((rTable.GetTableBox("B1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
466 CPPUNIT_ASSERT(((rTable.GetTableBox("B2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
467 CPPUNIT_ASSERT(((rTable.GetTableBox("B3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
468 CPPUNIT_ASSERT(((rTable.GetTableBox("C1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
469 CPPUNIT_ASSERT(((rTable.GetTableBox("C2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
470 CPPUNIT_ASSERT(((rTable.GetTableBox("C3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
471 //undo the changes, make cells [un]protected
472 rUndoManager.Undo();
473 //checking each cell's protection, it should be [un]protected
474 CPPUNIT_ASSERT(!((rTable.GetTableBox("A1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
475 CPPUNIT_ASSERT(!((rTable.GetTableBox("A2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
476 CPPUNIT_ASSERT(!((rTable.GetTableBox("A3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
477 CPPUNIT_ASSERT(!((rTable.GetTableBox("B1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
478 CPPUNIT_ASSERT(!((rTable.GetTableBox("B2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
479 CPPUNIT_ASSERT(!((rTable.GetTableBox("B3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
480 CPPUNIT_ASSERT(!((rTable.GetTableBox("C1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
481 CPPUNIT_ASSERT(!((rTable.GetTableBox("C2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
482 CPPUNIT_ASSERT(!((rTable.GetTableBox("C3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
483 //redo the changes, make cells protected
484 rUndoManager.Redo();
485 //checking each cell's protection, it should be protected
486 CPPUNIT_ASSERT(((rTable.GetTableBox("A1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
487 CPPUNIT_ASSERT(((rTable.GetTableBox("A2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
488 CPPUNIT_ASSERT(((rTable.GetTableBox("A3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
489 CPPUNIT_ASSERT(((rTable.GetTableBox("B1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
490 CPPUNIT_ASSERT(((rTable.GetTableBox("B2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
491 CPPUNIT_ASSERT(((rTable.GetTableBox("B3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
492 CPPUNIT_ASSERT(((rTable.GetTableBox("C1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
493 CPPUNIT_ASSERT(((rTable.GetTableBox("C2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
494 CPPUNIT_ASSERT(((rTable.GetTableBox("C3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
495 //moving the cursor to the starting of the document
496 pWrtShell->StartOfSection();
497 //making the table [un]protected
498 pWrtShell->SelTable();
499 pWrtShell->UnProtectCells();
500 //checking each cell's protection, it should be [un]protected
501 CPPUNIT_ASSERT(!((rTable.GetTableBox("A1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
502 CPPUNIT_ASSERT(!((rTable.GetTableBox("A2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
503 CPPUNIT_ASSERT(!((rTable.GetTableBox("A3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
504 CPPUNIT_ASSERT(!((rTable.GetTableBox("B1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
505 CPPUNIT_ASSERT(!((rTable.GetTableBox("B2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
506 CPPUNIT_ASSERT(!((rTable.GetTableBox("B3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
507 CPPUNIT_ASSERT(!((rTable.GetTableBox("C1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
508 CPPUNIT_ASSERT(!((rTable.GetTableBox("C2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
509 CPPUNIT_ASSERT(!((rTable.GetTableBox("C3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
510 //undo the changes, make cells protected
511 rUndoManager.Undo();
512 //checking each cell's protection, it should be protected
513 CPPUNIT_ASSERT(((rTable.GetTableBox("A1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
514 CPPUNIT_ASSERT(((rTable.GetTableBox("A2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
515 CPPUNIT_ASSERT(((rTable.GetTableBox("A3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
516 CPPUNIT_ASSERT(((rTable.GetTableBox("B1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
517 CPPUNIT_ASSERT(((rTable.GetTableBox("B2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
518 CPPUNIT_ASSERT(((rTable.GetTableBox("B3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
519 CPPUNIT_ASSERT(((rTable.GetTableBox("C1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
520 CPPUNIT_ASSERT(((rTable.GetTableBox("C2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
521 CPPUNIT_ASSERT(((rTable.GetTableBox("C3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
522 //redo the changes, make cells [un]protected
523 rUndoManager.Redo();
524 //checking each cell's protection, it should be [un]protected
525 CPPUNIT_ASSERT(!((rTable.GetTableBox("A1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
526 CPPUNIT_ASSERT(!((rTable.GetTableBox("A2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
527 CPPUNIT_ASSERT(!((rTable.GetTableBox("A3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
528 CPPUNIT_ASSERT(!((rTable.GetTableBox("B1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
529 CPPUNIT_ASSERT(!((rTable.GetTableBox("B2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
530 CPPUNIT_ASSERT(!((rTable.GetTableBox("B3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
531 CPPUNIT_ASSERT(!((rTable.GetTableBox("C1"))->GetFrameFormat()->GetProtect()).IsContentProtected());
532 CPPUNIT_ASSERT(!((rTable.GetTableBox("C2"))->GetFrameFormat()->GetProtect()).IsContentProtected());
533 CPPUNIT_ASSERT(!((rTable.GetTableBox("C3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
536 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf155685)
538 createSwDoc("table-at-end-of-cell.fodt");
539 SwDoc* pDoc = getSwDoc();
540 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
541 pWrtShell->GoNextCell();
542 pWrtShell->GoNextCell();
543 pWrtShell->GoNextCell();
544 pWrtShell->SelAll();
545 pWrtShell->Delete();
546 // this crashed
547 pWrtShell->Undo();
548 pWrtShell->Undo();
549 pWrtShell->Redo();
550 // this crashed
551 pWrtShell->Redo();
554 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf147220)
556 createSwDoc();
557 SwDoc* pDoc = getSwDoc();
558 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
560 pWrtShell->Insert(u"él");
562 // hide and enable
563 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
564 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
565 CPPUNIT_ASSERT(pDoc->getIDocumentRedlineAccess().IsRedlineOn());
566 CPPUNIT_ASSERT(
567 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
568 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
570 pWrtShell->GoStartSentence();
571 pWrtShell->SetMark();
572 pWrtShell->GoEndSentence();
574 // this did not remove the original text from the layout
575 pWrtShell->Replace(u"Él", false);
577 // currently the deleted text is before the replacement text, not sure if
578 // that is really required
579 CPPUNIT_ASSERT_EQUAL(OUString(u"élÉl"),
580 pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode()->GetText());
581 CPPUNIT_ASSERT_EQUAL(OUString(u"Él"),
582 static_cast<SwTextFrame const*>(pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode()->getLayoutFrame(nullptr))->GetText());
584 SwRedlineTable const& rRedlines(pDoc->getIDocumentRedlineAccess().GetRedlineTable());
585 CPPUNIT_ASSERT_EQUAL(SwRedlineTable::size_type(2), rRedlines.size());
586 CPPUNIT_ASSERT_EQUAL(RedlineType::Delete, rRedlines[0]->GetType());
587 CPPUNIT_ASSERT_EQUAL(OUString(u"él"), rRedlines[0]->GetText());
588 CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rRedlines[1]->GetType());
589 CPPUNIT_ASSERT_EQUAL(OUString(u"Él"), rRedlines[1]->GetText());
592 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf135978)
594 createSwDoc();
595 SwDoc* pDoc = getSwDoc();
596 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
598 pWrtShell->Insert("foobar");
599 pWrtShell->SplitNode();
600 pWrtShell->Insert("bazquux");
602 CPPUNIT_ASSERT(pWrtShell->IsEndOfDoc());
604 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
605 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
606 SfxItemSet flySet(pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>);
607 flySet.Put(anchor);
608 SwFlyFrameFormat const* pFly = dynamic_cast<SwFlyFrameFormat const*>(
609 pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true));
610 CPPUNIT_ASSERT(pFly != nullptr);
611 CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
612 // move cursor back to body
613 pWrtShell->SttEndDoc(/*bStt=*/false);
615 // hide and enable
616 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
617 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
619 CPPUNIT_ASSERT(pDoc->getIDocumentRedlineAccess().IsRedlineOn());
620 CPPUNIT_ASSERT(
621 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
622 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
624 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
625 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 6, /*bBasicCall=*/false);
626 pWrtShell->Delete();
628 // now split
629 pWrtShell->SttEndDoc(/*bStt=*/true);
630 pWrtShell->SplitNode();
631 CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
633 // the problem was that undo removed the fly frame from the layout
634 pWrtShell->Undo();
635 CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
637 pWrtShell->Redo();
638 CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
640 pWrtShell->Undo();
641 CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
644 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo75110)
646 createSwDoc("fdo75110.odt");
647 SwDoc* pDoc = getSwDoc();
648 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
650 pWrtShell->SelAll();
651 // The problem was that SwEditShell::DeleteSel() what this Delete() invokes took the wrong selection...
652 pWrtShell->Delete();
653 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
654 // ... so this Undo() call resulted in a crash.
655 rUndoManager.Undo();
658 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo75898)
660 createSwDoc("fdo75898.odt");
661 SwDoc* pDoc = getSwDoc();
662 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
663 pWrtShell->SelAll();
664 pWrtShell->InsertRow(1, true);
665 pWrtShell->InsertRow(1, true);
667 // Now check if the table has 3 lines.
668 SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
669 SwTableNode* pTableNode = pShellCursor->Start()->GetNode().FindTableNode();
670 // This was 1, when doing the same using the UI, Writer even crashed.
671 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pTableNode->GetTable().GetTabLines().size());
674 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testReplaceBackward)
676 //Regression test of fdo#70143
677 //EDITING: undo search&replace corrupt text when searching backward
678 createSwDoc();
679 SwDoc* pDoc = getSwDoc();
681 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
683 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
684 SwPaM aPaM(aIdx);
686 pDoc->getIDocumentContentOperations().InsertString(aPaM, "toto titi tutu");
687 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
688 lcl_selectCharacters(aPaM, 9, 5);
690 pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, "toto", false);
692 CPPUNIT_ASSERT_EQUAL(OUString(EXPECTED_REPLACE_CONTENT), pTextNode->GetText());
694 rUndoManager.Undo();
696 CPPUNIT_ASSERT_EQUAL(OUString(ORIGINAL_REPLACE_CONTENT), pTextNode->GetText());
699 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo69893)
701 createSwDoc("fdo69893.odt");
702 SwDoc* pDoc = getSwDoc();
703 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
705 pWrtShell->SelAll(); // A1 is empty -> selects the whole table.
706 pWrtShell->SelAll(); // Selects the whole document.
708 SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
709 SwTextNode& rEnd = dynamic_cast<SwTextNode&>(pShellCursor->End()->GetNode());
710 // Selection did not include the para after table, this was "B1".
711 CPPUNIT_ASSERT_EQUAL(OUString("Para after table."), rEnd.GetText());
714 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo70807)
716 createSwDoc("fdo70807.odt");
718 uno::Reference<container::XIndexAccess> xStylesIter(getStyles("PageStyles"), uno::UNO_QUERY);
720 for (sal_Int32 i = 0; i < xStylesIter->getCount(); ++i)
722 uno::Reference<style::XStyle> xStyle(xStylesIter->getByIndex(i), uno::UNO_QUERY);
724 bool expectedUsedStyle = false;
725 bool expectedUserDefined = false;
727 OUString styleName(xStyle->getName());
729 // just these styles are user defined styles
730 if (styleName == "pagestyle1" || styleName == "pagestyle2")
731 expectedUserDefined = true;
733 // just these styles are used in the document
734 if (styleName == "Right Page" || styleName == "pagestyle1" || styleName == "pagestyle2")
735 expectedUsedStyle = true;
737 CPPUNIT_ASSERT_EQUAL(expectedUserDefined, bool(xStyle->isUserDefined()));
738 CPPUNIT_ASSERT_EQUAL(expectedUsedStyle, bool(xStyle->isInUse()));
742 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testImportRTF)
744 // Insert "foobar" and position the cursor between "foo" and "bar".
745 createSwDoc();
746 SwDoc* pDoc = getSwDoc();
747 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
748 pWrtShell->Insert("foobar");
749 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 3, /*bBasicCall=*/false);
751 // Insert the RTF at the cursor position.
752 OString aData = "{\\rtf1 Hello world!\\par}";
753 SvMemoryStream aStream(const_cast<char*>(aData.getStr()), aData.getLength(), StreamMode::READ);
754 SwReader aReader(aStream, OUString(), OUString(), *pWrtShell->GetCursor());
755 Reader* pRTFReader = SwReaderWriter::GetRtfReader();
756 CPPUNIT_ASSERT(pRTFReader != nullptr);
757 CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, aReader.Read(*pRTFReader));
759 SwNodeOffset nIndex = pWrtShell->GetCursor()->GetPointNode().GetIndex();
760 CPPUNIT_ASSERT_EQUAL(OUString("fooHello world!"), pDoc->GetNodes()[nIndex - 1]->GetTextNode()->GetText());
761 CPPUNIT_ASSERT_EQUAL(OUString("bar"), pDoc->GetNodes()[nIndex]->GetTextNode()->GetText());
764 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testExportRTF)
766 // Insert "aaabbbccc" and select "bbb".
767 createSwDoc();
768 SwDoc* pDoc = getSwDoc();
769 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
770 pWrtShell->Insert("aaabbbccc");
771 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 3, /*bBasicCall=*/false);
772 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 3, /*bBasicCall=*/false);
774 // Create the clipboard document.
775 rtl::Reference<SwDoc> xClpDoc(new SwDoc());
776 xClpDoc->SetClipBoard(true);
777 pWrtShell->Copy(*xClpDoc);
779 // And finally export it as RTF.
780 WriterRef xWrt;
781 SwReaderWriter::GetWriter(u"RTF", OUString(), xWrt);
782 SvMemoryStream aStream;
783 SwWriter aWrt(aStream, *xClpDoc);
784 aWrt.Write(xWrt);
786 OString aData(static_cast<const char*>(aStream.GetData()), aStream.GetSize());
788 //Amusingly eventually there was a commit id with "ccc" in it, and so the rtf contained
789 //{\*\generator LibreOfficeDev/4.4.0.0.alpha0$Linux_X86_64 LibreOffice_project/f70664ccc6837f2cc21a29bb4f44e41e100efe6b}
790 //so the test fell over. so strip the generator tag
791 sal_Int32 nGeneratorStart = aData.indexOf("{\\*\\generator ");
792 CPPUNIT_ASSERT(nGeneratorStart != -1);
793 sal_Int32 nGeneratorEnd = aData.indexOf('}', nGeneratorStart + 1);
794 CPPUNIT_ASSERT(nGeneratorEnd != -1);
795 aData = aData.replaceAt(nGeneratorStart, nGeneratorEnd-nGeneratorStart+1, "");
797 CPPUNIT_ASSERT(aData.startsWith("{\\rtf1"));
798 CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aData.indexOf("aaa"));
799 CPPUNIT_ASSERT(aData.indexOf("bbb") != -1);
800 CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aData.indexOf("ccc"));
801 // Ensure there's no extra newline
802 CPPUNIT_ASSERT(aData.endsWith("bbb}" SAL_NEWLINE_STRING "}"));
805 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOCXAutoTextEmpty)
807 // file contains normal content but no AutoText
808 std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-empty.dotx", true);
809 CPPUNIT_ASSERT(pGlossary != nullptr);
812 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOCXAutoTextMultiple)
814 // file contains three AutoText entries
815 std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-multiple.dotx");
817 // check entries count
818 CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), pGlossary->GetCount());
820 // check names of entries, sorted order
821 CPPUNIT_ASSERT_EQUAL(OUString("Anothercomplex"), pGlossary->GetLongName(0));
822 CPPUNIT_ASSERT_EQUAL(OUString("Multiple"), pGlossary->GetLongName(1));
823 CPPUNIT_ASSERT_EQUAL(OUString("Second Autotext"), pGlossary->GetLongName(2));
825 // check if previously loaded content is correct (eg. doesn't contain title)
826 SwDoc* pDoc = pGlossary->GetDoc();
827 CPPUNIT_ASSERT(pDoc != nullptr);
829 SwNodeIndex aDocEnd(pDoc->GetNodes().GetEndOfContent());
830 SwNodeIndex aStart(*aDocEnd.GetNode().StartOfSectionNode(), 1);
832 CPPUNIT_ASSERT(aStart < aDocEnd);
834 // first line
835 SwNode& rNode = aStart.GetNode();
836 CPPUNIT_ASSERT(rNode.IsTextNode());
837 SwTextNode& rTextNode = *rNode.GetTextNode();
838 CPPUNIT_ASSERT_EQUAL(OUString("Another "), rTextNode.GetText());
840 // Make sure that autotext does not set a custom page style, leading to an unexpected page break
841 // on insertion.
842 // Without the accompanying fix in place, this test would have failed: the text node had an
843 // attribute set containing a page style item.
844 CPPUNIT_ASSERT(!rTextNode.HasSwAttrSet() || !rTextNode.GetSwAttrSet().HasItem(RES_PAGEDESC));
846 // last line
847 SwNodeIndex aLast(*aDocEnd.GetNode().EndOfSectionNode(), -1);
848 SwNode& rLastNode = aLast.GetNode();
849 CPPUNIT_ASSERT_EQUAL(OUString("complex"), rLastNode.GetTextNode()->GetText());
852 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOTMAutoText)
854 // this is dotm file difference is that in the dotm
855 // there are no empty paragraphs at the end of each entry
856 std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-dotm.dotm");
858 SwDoc* pDoc = pGlossary->GetDoc();
859 CPPUNIT_ASSERT(pDoc != nullptr);
861 // check if content is correct
862 SwNodeIndex aDocEnd(pDoc->GetNodes().GetEndOfContent());
863 SwNodeIndex aStart(*aDocEnd.GetNode().StartOfSectionNode(), 1);
864 SwNode& rNode = aStart.GetNode();
865 CPPUNIT_ASSERT_EQUAL(OUString("paragraph"), rNode.GetTextNode()->GetText());
868 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOCXAutoTextGallery)
870 // this file contains one AutoText entry and other
871 // entries which are not AutoText (have different "gallery" value)
872 std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-gallery.dotx");
874 SwDoc* pDoc = pGlossary->GetDoc();
875 CPPUNIT_ASSERT(pDoc != nullptr);
877 // check entries count
878 CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), pGlossary->GetCount());
880 // check entry name (if not contains gallery type)
881 CPPUNIT_ASSERT_EQUAL(OUString("Multiple"), pGlossary->GetLongName(0));
884 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testWatermarkDOCX)
886 createSwDoc("watermark.docx");
887 SwDoc* const pDoc = getSwDoc();
888 SwDocShell* pDocShell = pDoc->GetDocShell();
889 const SfxWatermarkItem* pWatermark;
890 SfxItemState eState = pDocShell->GetViewShell()->GetViewFrame().GetDispatcher()->QueryState(SID_WATERMARK, pWatermark);
892 CPPUNIT_ASSERT(eState >= SfxItemState::DEFAULT);
893 CPPUNIT_ASSERT(pWatermark);
894 CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(SID_WATERMARK), pWatermark->Which());
896 CPPUNIT_ASSERT_EQUAL(OUString("CustomWatermark"), pWatermark->GetText());
897 CPPUNIT_ASSERT_EQUAL(OUString("DejaVu Sans Light"), pWatermark->GetFont());
898 CPPUNIT_ASSERT_EQUAL(sal_Int16(45), pWatermark->GetAngle());
899 CPPUNIT_ASSERT_EQUAL(Color(0x548dd4), pWatermark->GetColor());
900 CPPUNIT_ASSERT_EQUAL(sal_Int16(50), pWatermark->GetTransparency());
903 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testWatermarkPosition)
905 // tdf#108494 Watermark inserted in the document with page break was outside the first page
906 const int aPagesInDocument = 2;
907 const int aAdditionalPagesCount[] = { 0, 0, 1, 1, 5, 5, 20, 20 };
908 const bool aChangeHeader[] = { true, false, true, false, true, false, true, false };
910 for (tools::ULong i = 0; i < sizeof(aAdditionalPagesCount) / sizeof(int); ++i)
912 int aPages = aPagesInDocument + aAdditionalPagesCount[i];
914 // Empty document with one Page Break
915 createSwDoc("watermark-position.odt");
916 SwDoc* pDoc = getSwDoc();
917 SwEditShell* pEditShell = pDoc->GetEditShell();
918 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
919 uno::Reference<frame::XModel> xModel = pDoc->GetDocShell()->GetBaseModel();
920 uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xModel, uno::UNO_QUERY);
921 uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
923 // 1. Add additional page breaks
924 for (int j = 0; j < aAdditionalPagesCount[i]; ++j)
925 pWrtShell->InsertPageBreak();
927 // 2. Change header state (On, Off, On)
928 if (aChangeHeader[i])
930 SwPageDesc aDesc(pDoc->GetPageDesc(0));
931 SwFrameFormat& rMaster = aDesc.GetMaster();
932 rMaster.SetFormatAttr(SwFormatHeader(true));
933 pDoc->ChgPageDesc(0, aDesc);
935 aDesc = pDoc->GetPageDesc(0);
936 SwFrameFormat& rMaster2 = aDesc.GetMaster();
937 rMaster2.SetFormatAttr(SwFormatHeader(false));
938 pDoc->ChgPageDesc(0, aDesc);
940 aDesc = pDoc->GetPageDesc(0);
941 SwFrameFormat& rMaster3 = aDesc.GetMaster();
942 rMaster3.SetFormatAttr(SwFormatHeader(true));
943 pDoc->ChgPageDesc(0, aDesc);
946 // 3. Insert Watermark
947 SfxWatermarkItem aWatermark;
948 aWatermark.SetText("Watermark");
949 aWatermark.SetFont("DejaVu Sans");
951 pEditShell->SetWatermark(aWatermark);
953 uno::Reference<css::drawing::XShape> xShape = getShape(1);
954 CPPUNIT_ASSERT(xShape.is());
956 SdrPage* pPage = pWrtShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
958 // Get Watermark object
959 SdrObject* pObject = pPage->GetObj(0);
960 pObject->RecalcBoundRect();
961 const tools::Rectangle& rRect = pObject->GetSnapRect();
962 Size rSize = pPage->GetSize();
964 // Page break, calculate height of a page
965 const int nPageHeight = rSize.getHeight() / aPages;
967 std::stringstream aMessage;
968 aMessage << "Case: " << i << ", nPageHeight = " << nPageHeight << ", rRect.Bottom = " << rRect.Bottom();
970 // Check if Watermark is inside a page
971 CPPUNIT_ASSERT_MESSAGE(aMessage.str(), nPageHeight >= rRect.Bottom());
973 // Check if Watermark is centered
974 CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, getProperty<sal_Int16>(xShape, "HoriOrient"));
975 CPPUNIT_ASSERT_EQUAL(text::VertOrientation::CENTER, getProperty<sal_Int16>(xShape, "VertOrient"));
979 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo74981)
981 // create a document with an input field
982 createSwDoc();
983 SwDoc* pDoc = getSwDoc();
984 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
985 SwInputField aField(static_cast<SwInputFieldType*>(pWrtShell->GetFieldType(0, SwFieldIds::Input)), "foo", "bar", 0, 0);
986 pWrtShell->InsertField2(aField);
989 // expect hints
990 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
991 SwTextNode* pTextNode = aIdx.GetNode().GetTextNode();
992 CPPUNIT_ASSERT(pTextNode->HasHints());
995 // go to the begin of the paragraph and split this node
996 pWrtShell->Left(SwCursorSkipMode::Chars, false, 100, false);
997 pWrtShell->SplitNode();
1000 // expect only the second paragraph to have hints
1001 SwNodeIndex aIdx(SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1));
1002 SwTextNode* pTextNode = aIdx.GetNode().GetTextNode();
1003 CPPUNIT_ASSERT(pTextNode->HasHints());
1004 --aIdx;
1005 pTextNode = aIdx.GetNode().GetTextNode();
1006 CPPUNIT_ASSERT(!pTextNode->HasHints());
1010 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf98512)
1012 createSwDoc();
1013 SwDoc* pDoc = getSwDoc();
1014 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1015 SwInputFieldType *const pType(static_cast<SwInputFieldType*>(
1016 pWrtShell->GetFieldType(0, SwFieldIds::Input)));
1017 SwInputField aField1(pType, "foo", "bar", INP_TXT, 0);
1018 pWrtShell->InsertField2(aField1);
1019 pWrtShell->SttEndDoc(/*bStt=*/true);
1020 SwInputField aField2(pType, "baz", "quux", INP_TXT, 0);
1021 pWrtShell->InsertField2(aField2);
1022 pWrtShell->SttEndDoc(/*bStt=*/true);
1023 pWrtShell->SetMark();
1024 pWrtShell->SttEndDoc(/*bStt=*/false);
1025 OUString const expected1(
1026 OUStringChar(CH_TXT_ATR_INPUTFIELDSTART) + "foo" + OUStringChar(CH_TXT_ATR_INPUTFIELDEND));
1027 OUString const expected2(
1028 OUStringChar(CH_TXT_ATR_INPUTFIELDSTART) + "baz" + OUStringChar(CH_TXT_ATR_INPUTFIELDEND)
1029 + expected1);
1030 CPPUNIT_ASSERT_EQUAL(expected2, pWrtShell->getShellCursor(false)->GetText());
1031 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1032 rUndoManager.Undo();
1033 pWrtShell->SttEndDoc(/*bStt=*/true);
1034 pWrtShell->SetMark();
1035 pWrtShell->SttEndDoc(/*bStt=*/false);
1036 CPPUNIT_ASSERT_EQUAL(expected1, pWrtShell->getShellCursor(false)->GetText());
1037 rUndoManager.Redo();
1038 pWrtShell->SttEndDoc(/*bStt=*/true);
1039 pWrtShell->SetMark();
1040 pWrtShell->SttEndDoc(/*bStt=*/false);
1041 CPPUNIT_ASSERT_EQUAL(expected2, pWrtShell->getShellCursor(false)->GetText());
1042 rUndoManager.Undo();
1043 pWrtShell->SttEndDoc(/*bStt=*/true);
1044 pWrtShell->SetMark();
1045 pWrtShell->SttEndDoc(/*bStt=*/false);
1046 CPPUNIT_ASSERT_EQUAL(expected1, pWrtShell->getShellCursor(false)->GetText());
1049 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxSelect)
1051 createSwDoc("shape-textbox.odt");
1052 SwDoc* pDoc = getSwDoc();
1053 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1054 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1055 SdrObject* pObject = pPage->GetObj(1);
1056 SwContact* pTextBox = static_cast<SwContact*>(pObject->GetUserCall());
1057 // First, make sure that pTextBox is a fly frame (textbox of a shape).
1058 CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_FLYFRMFMT), pTextBox->GetFormat()->Which());
1060 // Then select it.
1061 pWrtShell->SelectObj(Point(), 0, pObject);
1062 const SdrMarkList& rMarkList = pWrtShell->GetDrawView()->GetMarkedObjectList();
1063 SwDrawContact* pShape = static_cast<SwDrawContact*>(rMarkList.GetMark(0)->GetMarkedSdrObj()->GetUserCall());
1064 // And finally make sure the shape got selected, not just the textbox itself.
1065 CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_DRAWFRMFMT), pShape->GetFormat()->Which());
1068 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxDelete)
1070 createSwDoc("shape-textbox.odt");
1071 SwDoc* pDoc = getSwDoc();
1072 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1073 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1074 SdrObject* pObject = pPage->GetObj(0);
1075 pWrtShell->SelectObj(Point(), 0, pObject);
1076 size_t nActual = pPage->GetObjCount();
1077 // Two objects on the draw page: the shape and its textbox.
1078 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), nActual);
1080 pWrtShell->DelSelectedObj();
1081 nActual = pPage->GetObjCount();
1082 // Both (not only the shape) should be removed by now (the textbox wasn't removed, so this was 1).
1083 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), nActual);
1086 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testAnchorChangeSelection)
1088 createSwDoc("test_anchor_as_character.odt");
1089 SwDoc* pDoc = getSwDoc();
1090 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1091 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1092 SdrObject* pObject = pPage->GetObj(0);
1093 CPPUNIT_ASSERT(pObject);
1095 // Then select it.
1096 pWrtShell->SelectObj(Point(), 0, pObject);
1097 const SdrMarkList& rMarkList = pWrtShell->GetDrawView()->GetMarkedObjectList();
1098 CPPUNIT_ASSERT_EQUAL(pObject, rMarkList.GetMark(0)->GetMarkedSdrObj());
1100 pWrtShell->ChgAnchor(RndStdIds::FLY_AS_CHAR);
1102 // tdf#125039 shape must still be selected, extensions depend on that
1103 CPPUNIT_ASSERT_EQUAL(pObject, rMarkList.GetMark(0)->GetMarkedSdrObj());
1106 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCp1000071)
1108 createSwDoc("cp1000071.odt");
1109 SwDoc* pDoc = getSwDoc();
1110 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1112 const SwRedlineTable& rTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
1113 CPPUNIT_ASSERT_EQUAL( SwRedlineTable::size_type( 2 ), rTable.size());
1114 SwNodeOffset redlineStart0NodeIndex = rTable[ 0 ]->Start()->GetNodeIndex();
1115 sal_Int32 redlineStart0Index = rTable[ 0 ]->Start()->GetContentIndex();
1116 SwNodeOffset redlineEnd0NodeIndex = rTable[ 0 ]->End()->GetNodeIndex();
1117 sal_Int32 redlineEnd0Index = rTable[ 0 ]->End()->GetContentIndex();
1118 SwNodeOffset redlineStart1NodeIndex = rTable[ 1 ]->Start()->GetNodeIndex();
1119 sal_Int32 redlineStart1Index = rTable[ 1 ]->Start()->GetContentIndex();
1120 SwNodeOffset redlineEnd1NodeIndex = rTable[ 1 ]->End()->GetNodeIndex();
1121 sal_Int32 redlineEnd1Index = rTable[ 1 ]->End()->GetContentIndex();
1123 // Change the document layout to be 2 columns, and then undo.
1124 pWrtShell->SelAll();
1125 SwSectionData section(SectionType::Content, pWrtShell->GetUniqueSectionName());
1126 SfxItemSet set( pDoc->GetDocShell()->GetPool(), svl::Items<RES_COL, RES_COL> );
1127 SwFormatCol col;
1128 col.Init( 2, 0, 10000 );
1129 set.Put( col );
1130 pWrtShell->InsertSection( section, &set );
1131 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1132 rUndoManager.Undo();
1134 // Check that redlines are the same like at the beginning.
1135 CPPUNIT_ASSERT_EQUAL( SwRedlineTable::size_type( 2 ), rTable.size());
1136 CPPUNIT_ASSERT_EQUAL( redlineStart0NodeIndex, rTable[ 0 ]->Start()->GetNodeIndex());
1137 CPPUNIT_ASSERT_EQUAL( redlineStart0Index, rTable[ 0 ]->Start()->GetContentIndex());
1138 CPPUNIT_ASSERT_EQUAL( redlineEnd0NodeIndex, rTable[ 0 ]->End()->GetNodeIndex());
1139 CPPUNIT_ASSERT_EQUAL( redlineEnd0Index, rTable[ 0 ]->End()->GetContentIndex());
1140 CPPUNIT_ASSERT_EQUAL( redlineStart1NodeIndex, rTable[ 1 ]->Start()->GetNodeIndex());
1141 CPPUNIT_ASSERT_EQUAL( redlineStart1Index, rTable[ 1 ]->Start()->GetContentIndex());
1142 CPPUNIT_ASSERT_EQUAL( redlineEnd1NodeIndex, rTable[ 1 ]->End()->GetNodeIndex());
1143 CPPUNIT_ASSERT_EQUAL( redlineEnd1Index, rTable[ 1 ]->End()->GetContentIndex());
1146 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxVertadjust)
1148 createSwDoc("shape-textbox-vertadjust.odt");
1149 SwDoc* pDoc = getSwDoc();
1150 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1151 SdrObject* pObject = pPage->GetObj(1);
1152 SwFrameFormat* pFormat = static_cast<SwContact*>(pObject->GetUserCall())->GetFormat();
1153 // This was SDRTEXTVERTADJUST_TOP.
1154 CPPUNIT_ASSERT_EQUAL(SDRTEXTVERTADJUST_CENTER, pFormat->GetTextVertAdjust().GetValue());
1157 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxAutosize)
1159 createSwDoc("shape-textbox-autosize.odt");
1160 SwDoc* pDoc = getSwDoc();
1161 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1162 // 0-1 is the first UI-visible shape+textbox.
1163 SdrObject* pFirst = pPage->GetObj(0);
1164 CPPUNIT_ASSERT_EQUAL(OUString("1st"), pFirst->GetName());
1166 // 2-3 is the second UI-visible shape+textbox.
1167 SdrObject* pSecond = pPage->GetObj(2);
1168 CPPUNIT_ASSERT_EQUAL(OUString("2nd"), pSecond->GetName());
1170 // Shape -> textbox synchronization was missing, the second shape had the
1171 // same height as the first, even though the first contained 1 paragraph
1172 // and the other 2 ones.
1173 CPPUNIT_ASSERT(pFirst->GetSnapRect().getOpenHeight() < pSecond->GetSnapRect().getOpenHeight());
1176 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo82191)
1178 createSwDoc("fdo82191.odt");
1179 SwDoc* pDoc = getSwDoc();
1180 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1181 // Make sure we have a single draw shape.
1182 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), SwTextBoxHelper::getCount(pPage));
1184 SwDoc aClipboard;
1185 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1186 SdrObject* pObject = pPage->GetObj(0);
1187 // Select it, then copy and paste.
1188 pWrtShell->SelectObj(Point(), 0, pObject);
1189 pWrtShell->Copy(aClipboard);
1190 pWrtShell->Paste(aClipboard);
1192 // This was one: the textbox of the shape wasn't copied.
1193 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), SwTextBoxHelper::getCount(*pDoc));
1196 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCommentedWord)
1198 // This word is commented. <- string in document
1199 // 123456789 <- character positions
1200 createSwDoc("commented-word.odt");
1201 SwDoc* pDoc = getSwDoc();
1202 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1203 // Move the cursor into the second word.
1204 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 5, /*bBasicCall=*/false);
1205 // Select the word.
1206 pWrtShell->SelWrd();
1208 // Make sure that not only the word, but its comment anchor is also selected.
1209 SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
1210 // This was 9, only "word", not "word<anchor character>" was selected.
1211 CPPUNIT_ASSERT_EQUAL(sal_Int32(10), pShellCursor->End()->GetContentIndex());
1213 // Test that getAnchor() points to "word", not to an empty string.
1214 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
1215 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
1216 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
1217 uno::Reference<text::XTextContent> xField(xFields->nextElement(), uno::UNO_QUERY);
1218 CPPUNIT_ASSERT_EQUAL(OUString("word"), xField->getAnchor()->getString());
1221 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTextFieldGetAnchorGetTextInFooter)
1223 createSwDoc("textfield-getanchor-gettext-in-footer.odt");
1225 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
1226 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
1227 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
1228 uno::Reference<text::XTextContent> xField(xFields->nextElement(), uno::UNO_QUERY);
1230 OUString value = xField->getAnchor()->getText()->getString();
1231 CPPUNIT_ASSERT_EQUAL(OUString("userfield_in_footer"), value );
1234 // Tests that a blank document is still blank after conversion
1235 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionBlank)
1238 // Given
1239 createSwDoc();
1240 SwDoc* pDoc = getSwDoc();
1241 SwView* pView = pDoc->GetDocShell()->GetView();
1242 const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
1243 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
1244 SwPaM aPaM(aIdx);
1246 // When
1247 SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, nullptr,
1248 i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
1249 true, false, false );
1250 aWrap.Convert();
1252 // Then
1253 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
1254 CPPUNIT_ASSERT_EQUAL(OUString(), pTextNode->GetText());
1258 // Tests that non Chinese text is unchanged after conversion
1259 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionNonChineseText)
1262 // Given
1263 createSwDoc();
1264 SwDoc* pDoc = getSwDoc();
1265 SwView* pView = pDoc->GetDocShell()->GetView();
1266 const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
1267 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
1268 SwPaM aPaM(aIdx);
1269 pDoc->getIDocumentContentOperations().InsertString(aPaM, NON_CHINESE_CONTENT);
1271 // When
1272 SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, nullptr,
1273 i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
1274 true, false, false );
1275 aWrap.Convert();
1277 // Then
1278 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
1279 CPPUNIT_ASSERT_EQUAL(OUString(NON_CHINESE_CONTENT), pTextNode->GetText());
1283 // Tests conversion of traditional Chinese characters to simplified Chinese
1284 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionTraditionalToSimplified)
1287 // Given
1288 createSwDoc();
1289 SwDoc* pDoc = getSwDoc();
1290 SwView* pView = pDoc->GetDocShell()->GetView();
1291 const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
1292 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
1293 SwPaM aPaM(aIdx);
1294 pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(CHINESE_TRADITIONAL_CONTENT));
1296 // When
1297 SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, nullptr,
1298 i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
1299 true, false, false );
1300 aWrap.Convert();
1302 // Then
1303 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
1304 CPPUNIT_ASSERT_EQUAL(OUString(CHINESE_SIMPLIFIED_CONTENT), pTextNode->GetText());
1308 // Tests conversion of simplified Chinese characters to traditional Chinese
1309 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionSimplifiedToTraditional)
1312 // Given
1313 createSwDoc();
1314 SwDoc* pDoc = getSwDoc();
1315 SwView* pView = pDoc->GetDocShell()->GetView();
1316 const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
1317 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
1318 SwPaM aPaM(aIdx);
1319 pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(CHINESE_SIMPLIFIED_CONTENT));
1321 // When
1322 SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_SIMPLIFIED, LANGUAGE_CHINESE_TRADITIONAL, nullptr,
1323 i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
1324 true, false, false );
1325 aWrap.Convert();
1327 // Then
1328 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
1329 CPPUNIT_ASSERT_EQUAL(OUString(CHINESE_TRADITIONAL_CONTENT), pTextNode->GetText());
1333 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo85554)
1335 // Load the document, it contains one shape with a textbox.
1336 createSwDoc("fdo85554.odt");
1338 // Add a second shape to the document.
1339 uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
1340 uno::Reference<drawing::XShape> xShape(xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
1341 xShape->setSize(awt::Size(10000, 10000));
1342 xShape->setPosition(awt::Point(1000, 1000));
1343 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
1344 uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
1345 xDrawPage->add(xShape);
1347 // Save it and load it back.
1348 saveAndReload("writer8");
1350 // This was 1, we lost a shape on export.
1351 CPPUNIT_ASSERT_EQUAL(2, getShapes());
1354 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testMergeDoc)
1356 createSwDoc("merge-change1.odt");
1357 SwDoc* pDoc1 = getSwDoc();
1359 auto xDoc2Component(loadFromDesktop(
1360 createFileURL(u"merge-change2.odt"),
1361 "com.sun.star.text.TextDocument"));
1362 auto pxDoc2Document(
1363 dynamic_cast<SwXTextDocument *>(xDoc2Component.get()));
1364 CPPUNIT_ASSERT(pxDoc2Document);
1365 SwDoc* const pDoc2(pxDoc2Document->GetDocShell()->GetDoc());
1367 SwEditShell* const pEditShell(pDoc1->GetEditShell());
1368 pEditShell->MergeDoc(*pDoc2);
1370 // accept all redlines
1371 while(pEditShell->GetRedlineCount())
1372 pEditShell->AcceptRedline(0);
1374 CPPUNIT_ASSERT_EQUAL(7, getParagraphs());
1375 getParagraph(1, "Para One: Two Three Four Five");
1376 getParagraph(2, "Para Two: One Three Four Five");
1377 getParagraph(3, "Para Three: One Two Four Five");
1378 getParagraph(4, "Para Four: One Two Three Four Five");
1379 getParagraph(5, "Para Six: One Three Four Five");
1380 getParagraph(6, "");
1381 getParagraph(7, "");
1383 xDoc2Component->dispose();
1386 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCreatePortions)
1388 createSwDoc("uno-cycle.odt");
1389 uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
1390 uno::Reference<text::XTextContent> xText(xBookmarksSupplier->getBookmarks()->getByName("Mark"), uno::UNO_QUERY);
1391 uno::Reference<container::XEnumerationAccess> xTextCursor(xText->getAnchor(), uno::UNO_QUERY);
1392 CPPUNIT_ASSERT(xTextCursor.is());
1394 uno::Reference<container::XEnumerationAccess> xParagraph(
1395 xTextCursor->createEnumeration()->nextElement(), uno::UNO_QUERY);
1396 CPPUNIT_ASSERT(xParagraph.is());
1397 // This looped forever in lcl_CreatePortions
1398 xParagraph->createEnumeration();
1401 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testBookmarkUndo)
1403 createSwDoc();
1404 SwDoc* pDoc = getSwDoc();
1405 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1406 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1407 SwPaM aPaM( SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1) );
1409 pMarkAccess->makeMark(aPaM, "Mark", IDocumentMarkAccess::MarkType::BOOKMARK,
1410 ::sw::mark::InsertMode::New);
1411 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1412 rUndoManager.Undo();
1413 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
1414 rUndoManager.Redo();
1415 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1417 IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findMark("Mark");
1418 CPPUNIT_ASSERT(ppBkmk != pMarkAccess->getAllMarksEnd());
1420 pMarkAccess->renameMark(*ppBkmk, "Mark_");
1421 CPPUNIT_ASSERT(bool(pMarkAccess->findMark("Mark") == pMarkAccess->getAllMarksEnd()));
1422 CPPUNIT_ASSERT(pMarkAccess->findMark("Mark_") != pMarkAccess->getAllMarksEnd());
1423 rUndoManager.Undo();
1424 CPPUNIT_ASSERT(pMarkAccess->findMark("Mark") != pMarkAccess->getAllMarksEnd());
1425 CPPUNIT_ASSERT(bool(pMarkAccess->findMark("Mark_") == pMarkAccess->getAllMarksEnd()));
1426 rUndoManager.Redo();
1427 CPPUNIT_ASSERT(bool(pMarkAccess->findMark("Mark") == pMarkAccess->getAllMarksEnd()));
1428 CPPUNIT_ASSERT(pMarkAccess->findMark("Mark_") != pMarkAccess->getAllMarksEnd());
1430 pMarkAccess->deleteMark(pMarkAccess->findMark("Mark_"), false);
1431 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
1432 rUndoManager.Undo();
1433 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1434 rUndoManager.Redo();
1435 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
1438 static void lcl_setWeight(SwWrtShell* pWrtShell, FontWeight aWeight)
1440 SvxWeightItem aWeightItem(aWeight, EE_CHAR_WEIGHT);
1441 SvxScriptSetItem aScriptSetItem(SID_ATTR_CHAR_WEIGHT, pWrtShell->GetAttrPool());
1442 aScriptSetItem.PutItemForScriptType(SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX, aWeightItem);
1443 pWrtShell->SetAttrSet(aScriptSetItem.GetItemSet());
1446 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo85876)
1448 createSwDoc();
1449 SwDoc* const pDoc = getSwDoc();
1450 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1451 lcl_setWeight(pWrtShell, WEIGHT_BOLD);
1452 pWrtShell->Insert("test");
1453 lcl_setWeight(pWrtShell, WEIGHT_NORMAL);
1454 pWrtShell->SplitNode();
1455 pWrtShell->SplitNode();
1456 pWrtShell->Up(false);
1457 pWrtShell->Insert("test");
1458 auto xText = getParagraph(1)->getText();
1459 CPPUNIT_ASSERT(xText.is());
1461 auto xCursor(xText->createTextCursorByRange(getParagraph(1)));
1462 CPPUNIT_ASSERT(xCursor.is());
1463 xCursor->collapseToStart();
1464 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, "CharWeight"));
1467 auto xCursor(xText->createTextCursorByRange(getParagraph(2)));
1468 CPPUNIT_ASSERT(xCursor.is());
1469 xCursor->collapseToStart();
1470 // this used to be BOLD too with fdo#85876
1471 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xCursor, "CharWeight"));
1475 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCaretPositionMovingUp)
1477 createSwDoc();
1478 SwDoc* const pDoc = getSwDoc();
1479 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1480 pWrtShell->Insert("after");
1481 pWrtShell->InsertLineBreak();
1482 pWrtShell->Up(false);
1483 pWrtShell->Insert("before");
1485 CPPUNIT_ASSERT_EQUAL(OUString(u"beforeAfter" + OUStringChar(CH_TXTATR_NEWLINE)), getParagraph(1)->getString());
1488 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf93441)
1490 createSwDoc();
1491 SwDoc* const pDoc = getSwDoc();
1492 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1493 pWrtShell->Insert("Hello");
1494 pWrtShell->InsertLineBreak();
1495 pWrtShell->Insert("Hello World");
1496 pWrtShell->Up(false);
1497 pWrtShell->Insert(" World");
1499 // Without the fix in place, this test would have failed with
1500 // - Expected: Hello World\nHello World
1501 // - Actual : WorldHello\nHello World
1502 CPPUNIT_ASSERT_EQUAL(OUString(u"Hello World" + OUStringChar(CH_TXTATR_NEWLINE) + u"Hello World"), getParagraph(1)->getString());
1505 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf81226)
1507 createSwDoc();
1508 SwDoc* const pDoc = getSwDoc();
1509 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1510 pWrtShell->Insert("before");
1511 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
1512 pWrtShell->Down(false);
1513 pWrtShell->Insert("after");
1515 // Without the fix in place, this test would have failed with
1516 // - Expected: beforeafter
1517 // - Actual : beafterfore
1518 CPPUNIT_ASSERT_EQUAL(OUString("beforeafter"), getParagraph(1)->getString());
1521 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf137532)
1523 createSwDoc();
1524 SwDoc* const pDoc = getSwDoc();
1525 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1526 pWrtShell->Insert("test");
1528 //Select the word and change it to bold
1529 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 4, /*bBasicCall=*/false);
1530 lcl_setWeight(pWrtShell, WEIGHT_BOLD);
1532 // Select first character and replace it
1533 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1534 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1535 pWrtShell->Insert("x");
1537 auto xText = getParagraph(1)->getText();
1538 CPPUNIT_ASSERT(xText.is());
1539 auto xCursor(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
1541 CPPUNIT_ASSERT(xCursor.is());
1542 CPPUNIT_ASSERT_EQUAL(OUString("xest"), xCursor->getString());
1543 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, "CharWeight"));
1545 dispatchCommand(mxComponent, ".uno:Undo", {});
1547 xCursor.set(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
1548 CPPUNIT_ASSERT(xCursor.is());
1549 CPPUNIT_ASSERT_EQUAL(OUString("test"), xCursor->getString());
1551 // Without the fix in place, this test would have failed in
1552 // - Expected: 150
1553 // - Actual : 100
1554 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, "CharWeight"));
1556 dispatchCommand(mxComponent, ".uno:Undo", {});
1558 xCursor.set(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
1559 CPPUNIT_ASSERT(xCursor.is());
1560 CPPUNIT_ASSERT_EQUAL(OUString("test"), xCursor->getString());
1561 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xCursor, "CharWeight"));
1564 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo87448)
1566 createSwDoc("fdo87448.odt");
1568 // Save the first shape to a metafile.
1569 uno::Reference<drawing::XGraphicExportFilter> xGraphicExporter = drawing::GraphicExportFilter::create(comphelper::getProcessComponentContext());
1570 uno::Reference<lang::XComponent> xSourceDoc(getShape(1), uno::UNO_QUERY);
1571 xGraphicExporter->setSourceDocument(xSourceDoc);
1573 SvMemoryStream aStream;
1574 uno::Reference<io::XOutputStream> xOutputStream(new utl::OStreamWrapper(aStream));
1575 uno::Sequence<beans::PropertyValue> aDescriptor( comphelper::InitPropertySequence({
1576 { "OutputStream", uno::Any(xOutputStream) },
1577 { "FilterName", uno::Any(OUString("SVM")) }
1578 }));
1579 xGraphicExporter->filter(aDescriptor);
1580 aStream.Seek(STREAM_SEEK_TO_BEGIN);
1582 // Read it back and dump it as an XML file.
1583 Graphic aGraphic;
1584 TypeSerializer aSerializer(aStream);
1585 aSerializer.readGraphic(aGraphic);
1586 const GDIMetaFile& rMetaFile = aGraphic.GetGDIMetaFile();
1587 MetafileXmlDump dumper;
1588 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, rMetaFile);
1590 // The first polyline in the document has a number of points to draw arcs,
1591 // the last one jumps back to the start, so we call "end" the last but one.
1592 sal_Int32 nFirstEnd = getXPath(pXmlDoc, "(//polyline)[1]/point[last()-1]", "x").toInt32();
1593 // The second polyline has a different start point, but the arc it draws
1594 // should end at the ~same position as the first polyline.
1595 sal_Int32 nSecondEnd = getXPath(pXmlDoc, "(//polyline)[2]/point[last()]", "x").toInt32();
1597 // nFirstEnd was 6023 and nSecondEnd was 6648, now they should be much closer, e.g. nFirstEnd = 6550, nSecondEnd = 6548
1598 OString aMsg = "nFirstEnd is " + OString::number(nFirstEnd) + ", nSecondEnd is " + OString::number(nSecondEnd);
1599 // Assert that the difference is less than half point.
1600 CPPUNIT_ASSERT_MESSAGE(aMsg.getStr(), abs(nFirstEnd - nSecondEnd) < 10);
1603 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTextCursorInvalidation)
1605 createSwDoc();
1606 SwDoc* pDoc = getSwDoc();
1607 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1608 uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
1609 CPPUNIT_ASSERT(xPageStyle.is());
1610 xPageStyle->setPropertyValue("HeaderIsOn", uno::Any(true));
1611 uno::Reference<text::XText> xHeader(getProperty<uno::Reference<text::XText>>(xPageStyle, "HeaderText"));
1612 CPPUNIT_ASSERT(xHeader.is());
1613 // create cursor inside the header text
1614 uno::Reference<text::XTextCursor> xCursor(xHeader->createTextCursor());
1615 // can't go right in empty header
1616 CPPUNIT_ASSERT(!xCursor->goRight(1, false));
1617 // this does not actually delete the header: xPageStyle->setPropertyValue("HeaderIsOn", uno::makeAny(false));
1618 pWrtShell->ChangeHeaderOrFooter(u"Default Page Style", true, false, false);
1619 // must be disposed after deleting header
1620 // cursor ends up in body
1621 // UPDATE: this behaviour has been corrected as a side effect of the fix to tdf#46561:
1622 //CPPUNIT_ASSERT_THROW(xCursor->goRight(1, false), uno::RuntimeException);
1625 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf68183)
1627 // First disable RSID and check if indeed no such attribute is inserted.
1628 createSwDoc();
1629 SwDoc* pDoc = getSwDoc();
1630 SW_MOD()->GetModuleConfig()->SetStoreRsid(false);
1631 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1632 pWrtShell->Insert2("X");
1634 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
1635 SwPaM aPaM(aIdx);
1636 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
1637 CPPUNIT_ASSERT_EQUAL(false, pTextNode->GetSwAttrSet().HasItem(RES_PARATR_RSID));
1639 // Then enable storing of RSID and make sure that the attribute is inserted.
1640 SW_MOD()->GetModuleConfig()->SetStoreRsid(true);
1642 pWrtShell->DelToStartOfLine();
1643 pWrtShell->Insert2("X");
1645 CPPUNIT_ASSERT_EQUAL(true, pTextNode->GetSwAttrSet().HasItem(RES_PARATR_RSID));
1648 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCp1000115)
1650 createSwDoc("cp1000115.fodt");
1651 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1652 // This was 1: the long paragraph in the B1 cell did flow over to the
1653 // second page, so there was only one paragraph in the second cell of the
1654 // second page.
1655 assertXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell[2]/txt", 2);
1658 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf63214)
1660 //This is a crash test
1661 createSwDoc();
1662 SwDoc* pDoc = getSwDoc();
1663 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1664 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1665 pWrtShell->Insert("V");
1666 { //limiting the lifetime of SwPaM with a nested scope
1667 //the shell cursor are automatically adjusted when nodes are deleted, but the shell doesn't know about an SwPaM on the stack
1668 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1669 SwPaM aPaM( SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1) );
1670 aPaM.SetMark();
1671 aPaM.Move(fnMoveForward, GoInContent);
1672 //Inserting a crossRefBookmark
1673 pMarkAccess->makeMark(aPaM, "Bookmark",
1674 IDocumentMarkAccess::MarkType::CROSSREF_HEADING_BOOKMARK,
1675 ::sw::mark::InsertMode::New);
1676 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1678 //moving cursor to the end of paragraph
1679 pWrtShell->EndPara();
1680 //inserting paragraph break
1681 pWrtShell->SplitNode();
1682 rUndoManager.Undo();
1683 rUndoManager.Redo();
1686 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf90003)
1688 createSwDoc("tdf90003.odt");
1689 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1690 CPPUNIT_ASSERT(pXmlDoc);
1691 // This was 1: an unexpected fly portion was created, resulting in too
1692 // large x position for the empty paragraph marker.
1693 assertXPath(pXmlDoc, "//SwFixPortion[@type='PortionType::Fly']", 0);
1696 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf51741)
1698 createSwDoc();
1699 SwDoc* pDoc = getSwDoc();
1700 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1701 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1702 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1703 SwPaM aPaM( SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1) );
1704 //Modification 1
1705 pMarkAccess->makeMark(aPaM, "Mark", IDocumentMarkAccess::MarkType::BOOKMARK,
1706 ::sw::mark::InsertMode::New);
1707 CPPUNIT_ASSERT(pWrtShell->IsModified());
1708 pWrtShell->ResetModified();
1709 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1710 //Modification 2
1711 rUndoManager.Undo();
1712 CPPUNIT_ASSERT(pWrtShell->IsModified());
1713 pWrtShell->ResetModified();
1714 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
1715 //Modification 3
1716 rUndoManager.Redo();
1717 CPPUNIT_ASSERT(pWrtShell->IsModified());
1718 pWrtShell->ResetModified();
1719 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1720 IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findMark("Mark");
1721 CPPUNIT_ASSERT(ppBkmk != pMarkAccess->getAllMarksEnd());
1722 //Modification 4
1723 pMarkAccess->renameMark(*ppBkmk, "Mark_");
1724 CPPUNIT_ASSERT(pWrtShell->IsModified());
1725 pWrtShell->ResetModified();
1726 CPPUNIT_ASSERT(bool(pMarkAccess->findMark("Mark") == pMarkAccess->getAllMarksEnd()));
1727 CPPUNIT_ASSERT(pMarkAccess->findMark("Mark_") != pMarkAccess->getAllMarksEnd());
1728 //Modification 5
1729 rUndoManager.Undo();
1730 CPPUNIT_ASSERT(pWrtShell->IsModified());
1731 pWrtShell->ResetModified();
1732 CPPUNIT_ASSERT(pMarkAccess->findMark("Mark") != pMarkAccess->getAllMarksEnd());
1733 CPPUNIT_ASSERT(bool(pMarkAccess->findMark("Mark_") == pMarkAccess->getAllMarksEnd()));
1734 //Modification 6
1735 rUndoManager.Redo();
1736 CPPUNIT_ASSERT(pWrtShell->IsModified());
1737 pWrtShell->ResetModified();
1738 CPPUNIT_ASSERT(bool(pMarkAccess->findMark("Mark") == pMarkAccess->getAllMarksEnd()));
1739 CPPUNIT_ASSERT(pMarkAccess->findMark("Mark_") != pMarkAccess->getAllMarksEnd());
1740 //Modification 7
1741 pMarkAccess->deleteMark(pMarkAccess->findMark("Mark_"), false);
1742 CPPUNIT_ASSERT(pWrtShell->IsModified());
1743 pWrtShell->ResetModified();
1744 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
1745 //Modification 8
1746 rUndoManager.Undo();
1747 CPPUNIT_ASSERT(pWrtShell->IsModified());
1748 pWrtShell->ResetModified();
1749 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1750 //Modification 9
1751 rUndoManager.Redo();
1752 CPPUNIT_ASSERT(pWrtShell->IsModified());
1753 pWrtShell->ResetModified();
1754 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
1757 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDefaultsOfOutlineNumbering)
1759 uno::Reference<text::XDefaultNumberingProvider> xDefNum(m_xSFactory->createInstance("com.sun.star.text.DefaultNumberingProvider"), uno::UNO_QUERY);
1760 css::lang::Locale alocale;
1761 alocale.Language = "en";
1762 alocale.Country = "US";
1763 const uno::Sequence<beans::PropertyValues> aPropVal(xDefNum->getDefaultContinuousNumberingLevels(alocale));
1764 CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aPropVal.getLength());
1765 for(const auto& rPropValues : aPropVal)
1767 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), rPropValues.getLength());
1768 for(const auto& rPropVal : rPropValues)
1770 uno::Any aAny = rPropVal.Value;
1771 if(rPropVal.Name == "Prefix" || rPropVal.Name == "Suffix" || rPropVal.Name == "Transliteration")
1772 CPPUNIT_ASSERT_EQUAL(OUString("string"), aAny.getValueTypeName());
1773 else if(rPropVal.Name == "NumberingType")
1774 CPPUNIT_ASSERT_EQUAL(OUString("short"), aAny.getValueTypeName());
1775 else if(rPropVal.Name == "NatNum")
1776 CPPUNIT_ASSERT_EQUAL(OUString("short"), aAny.getValueTypeName());
1777 //It is expected to be long but right now its short !error!
1778 else
1779 CPPUNIT_FAIL("Property Name not matched");
1784 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDeleteTableRedlines)
1786 createSwDoc();
1787 SwDoc* pDoc = getSwDoc();
1788 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1789 SwInsertTableOptions TableOpt(SwInsertTableFlags::DefaultBorder, 0);
1790 const SwTable& rTable = pWrtShell->InsertTable(TableOpt, 1, 3);
1791 uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
1792 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getRows()->getCount());
1793 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getColumns()->getCount());
1794 uno::Sequence<beans::PropertyValue> aDescriptor;
1795 SwUnoCursorHelper::makeTableCellRedline((*const_cast<SwTableBox*>(rTable.GetTableBox("A1"))), u"TableCellInsert", aDescriptor);
1796 SwUnoCursorHelper::makeTableCellRedline((*const_cast<SwTableBox*>(rTable.GetTableBox("B1"))), u"TableCellInsert", aDescriptor);
1797 SwUnoCursorHelper::makeTableCellRedline((*const_cast<SwTableBox*>(rTable.GetTableBox("C1"))), u"TableCellInsert", aDescriptor);
1798 IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess();
1799 SwExtraRedlineTable& rExtras = rIDRA.GetExtraRedlineTable();
1800 rExtras.DeleteAllTableRedlines(*pDoc, rTable, false, RedlineType::Any);
1801 CPPUNIT_ASSERT_EQUAL(o3tl::narrowing<sal_uInt16>(0), rExtras.GetSize());
1804 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testXFlatParagraph)
1806 createSwDoc();
1807 SwDoc* pDoc = getSwDoc();
1808 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1809 //Inserting some text in the document
1810 pWrtShell->Insert("This is sample text");
1811 pWrtShell->SplitNode();
1812 pWrtShell->Insert("This is another sample text");
1813 pWrtShell->SplitNode();
1814 pWrtShell->Insert("This is yet another sample text");
1815 //retrieving the XFlatParagraphs
1816 uno::Reference<text::XFlatParagraphIteratorProvider> xFPIP(mxComponent, uno::UNO_QUERY);
1817 uno::Reference<text::XFlatParagraphIterator> xFPIterator(xFPIP->getFlatParagraphIterator(sal_Int32(text::TextMarkupType::SPELLCHECK), true));
1818 uno::Reference<text::XFlatParagraph> xFlatPara(xFPIterator->getFirstPara());
1819 CPPUNIT_ASSERT_EQUAL(OUString("This is sample text"), xFlatPara->getText());
1820 //checking modified status
1821 CPPUNIT_ASSERT(!xFlatPara->isModified());
1822 //checking "checked" status, modifying it and asserting the changes
1823 CPPUNIT_ASSERT(!xFlatPara->isChecked(sal_Int32(text::TextMarkupType::SPELLCHECK)));
1824 xFlatPara->setChecked((sal_Int32(text::TextMarkupType::SPELLCHECK)), true);
1825 CPPUNIT_ASSERT(xFlatPara->isChecked(sal_Int32(text::TextMarkupType::SPELLCHECK)));
1826 //getting other XFlatParagraphs and asserting their contents
1827 uno::Reference<text::XFlatParagraph> xFlatPara2(xFPIterator->getParaAfter(xFlatPara));
1828 CPPUNIT_ASSERT_EQUAL(OUString("This is another sample text"), xFlatPara2->getText());
1829 uno::Reference<text::XFlatParagraph> xFlatPara3(xFPIterator->getParaAfter(xFlatPara2));
1830 CPPUNIT_ASSERT_EQUAL(OUString("This is yet another sample text"), xFlatPara3->getText());
1831 uno::Reference<text::XFlatParagraph> xFlatPara4(xFPIterator->getParaBefore(xFlatPara3));
1832 CPPUNIT_ASSERT_EQUAL(xFlatPara2->getText(), xFlatPara4->getText());
1833 //changing the attributes of last para
1834 uno::Sequence<beans::PropertyValue> aDescriptor( comphelper::InitPropertySequence({
1835 { "CharWeight", uno::Any(float(css::awt::FontWeight::BOLD)) }
1836 }));
1837 xFlatPara3->changeAttributes(sal_Int32(0), sal_Int32(5), aDescriptor);
1838 //checking Language Portions
1839 uno::Sequence<::sal_Int32> aLangPortions(xFlatPara4->getLanguagePortions());
1840 CPPUNIT_ASSERT(!aLangPortions.hasElements());
1841 //examining Language of text
1842 css::lang::Locale alocale = xFlatPara4->getLanguageOfText(sal_Int32(0), sal_Int32(4));
1843 CPPUNIT_ASSERT_EQUAL(OUString("en"), alocale.Language);
1844 CPPUNIT_ASSERT_EQUAL(OUString("US"), alocale.Country);
1845 //examining Primary Language of text
1846 css::lang::Locale aprimarylocale = xFlatPara4->getPrimaryLanguageOfText(sal_Int32(0), sal_Int32(20));
1847 CPPUNIT_ASSERT_EQUAL(OUString("en"), aprimarylocale.Language);
1848 CPPUNIT_ASSERT_EQUAL(OUString("US"), aprimarylocale.Country);
1851 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf81995)
1853 uno::Reference<text::XDefaultNumberingProvider> xDefNum(m_xSFactory->createInstance("com.sun.star.text.DefaultNumberingProvider"), uno::UNO_QUERY);
1854 css::lang::Locale alocale;
1855 alocale.Language = "en";
1856 alocale.Country = "US";
1857 const uno::Sequence<uno::Reference<container::XIndexAccess>> aIndexAccess(xDefNum->getDefaultOutlineNumberings(alocale));
1858 CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aIndexAccess.getLength());
1859 for(const auto& rIndexAccess : aIndexAccess)
1861 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), rIndexAccess->getCount());
1862 for(int j=0;j<rIndexAccess->getCount();j++)
1864 uno::Sequence<beans::PropertyValue> aProps;
1865 rIndexAccess->getByIndex(j) >>= aProps;
1866 CPPUNIT_ASSERT_EQUAL(sal_Int32(12), aProps.getLength());
1867 for(const beans::PropertyValue& rProp : std::as_const(aProps))
1869 uno::Any aAny = rProp.Value;
1870 if(rProp.Name == "Prefix" || rProp.Name == "Suffix" || rProp.Name == "BulletChar" || rProp.Name == "BulletFontName" || rProp.Name == "Transliteration")
1871 CPPUNIT_ASSERT_EQUAL(OUString("string"), aAny.getValueTypeName());
1872 else if(rProp.Name == "NumberingType" || rProp.Name == "ParentNumbering" || rProp.Name == "Adjust")
1873 CPPUNIT_ASSERT_EQUAL(OUString("short"), aAny.getValueTypeName());
1874 else if(rProp.Name == "LeftMargin" || rProp.Name == "SymbolTextDistance" || rProp.Name == "FirstLineOffset" || rProp.Name == "NatNum")
1875 CPPUNIT_ASSERT_EQUAL(OUString("long"), aAny.getValueTypeName());
1876 else
1877 CPPUNIT_FAIL("Property Name not matched");
1883 CPPUNIT_PLUGIN_IMPLEMENT();
1885 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */