remove assert looking for new compatibilityMode DOCX
[LibreOffice.git] / sw / qa / extras / uiwriter / uiwriter.cxx
blobdd683c11acce7e19520842c0c9ef1c221065137d
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(u"/sw/qa/extras/uiwriter/data/"_ustr)
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 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
111 // there is exactly one frame
112 CPPUNIT_ASSERT_EQUAL(1, getShapes());
114 RedlineFlags nMode = pWrtShell->GetRedlineFlags();
115 CPPUNIT_ASSERT(nMode & RedlineFlags::ShowDelete);
117 // hide delete redlines
118 pWrtShell->SetRedlineFlags(nMode & ~RedlineFlags::ShowDelete);
120 // there is still exactly one frame
121 CPPUNIT_ASSERT_EQUAL(1, getShapes());
123 pWrtShell->SetRedlineFlags(nMode); // show again
125 // there is still exactly one frame
126 CPPUNIT_ASSERT_EQUAL(1, getShapes());
129 //Replacement tests
131 constexpr OUString ORIGINAL_REPLACE_CONTENT(u"toto titi tutu"_ustr);
132 constexpr OUString EXPECTED_REPLACE_CONTENT(u"toto toto tutu"_ustr);
134 // Chinese conversion tests
136 const sal_Unicode CHINESE_TRADITIONAL_CONTENT(0x9F8D);
137 const sal_Unicode CHINESE_SIMPLIFIED_CONTENT(0x9F99);
138 constexpr OUString NON_CHINESE_CONTENT(u"Hippopotamus"_ustr);
140 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testReplaceForward)
142 createSwDoc();
143 SwDoc* pDoc = getSwDoc();
145 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
147 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
148 SwPaM aPaM(aIdx);
150 pDoc->getIDocumentContentOperations().InsertString(aPaM, ORIGINAL_REPLACE_CONTENT);
152 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
153 lcl_selectCharacters(aPaM, 5, 9);
154 pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, u"toto"_ustr, false);
156 CPPUNIT_ASSERT_EQUAL(EXPECTED_REPLACE_CONTENT, pTextNode->GetText());
158 rUndoManager.Undo();
160 CPPUNIT_ASSERT_EQUAL(ORIGINAL_REPLACE_CONTENT, pTextNode->GetText());
164 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtCharStartOutside0)
166 testRedlineFrame("redlineFrame.fodt");
169 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtCharStartOutside)
171 testRedlineFrame("redlineFrame_at_char_start_outside.fodt");
174 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtCharStartInside)
176 testRedlineFrame("redlineFrame_at_char_start_inside.fodt");
179 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtParaStartOutside)
181 testRedlineFrame("redline_fly_duplication_at_para_start_outside.fodt");
184 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtParaEndInside)
186 testRedlineFrame("redline_fly_duplication_at_para_end_inside.fodt");
189 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtParaOneParagraph)
191 // test ALLFLYS flag: oddly enough it didn't fail as fodt but failed as odt...
192 testRedlineFrame("redline_fly_at_para_one_paragraph.odt");
195 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtPara2ndParagraph)
197 // lost via the buggy increment in Copy
198 testRedlineFrame("redline_fly_duplication_at_para_2nd_paragraph.fodt");
201 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testThreadedException)
203 SvFileStream aFileStream(createFileURL(u"threadedException.fodt"), StreamMode::READ);
205 //threaded reading only kicks in if there is sufficient buffer to make it worthwhile, so read
206 //from a SvFileStream to ensure that
207 bool bRes = TestImportFODT(aFileStream);
209 CPPUNIT_ASSERT(!bRes);
212 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf149595)
214 createSwDoc("demo91.fodt");
216 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
218 // all 4 shapes are on the 2nd paragraph
219 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
220 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
221 CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
224 pWrtShell->Down(false);
225 pWrtShell->EndPara(/*bSelect=*/true);
226 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
228 // one shape is anchored in the middle, others at the start/end/at-para
229 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
230 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
231 CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
233 pWrtShell->Up(false);
234 dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
236 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() != nullptr);
237 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs()->size());
238 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
239 CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
241 pWrtShell->Undo();
242 pWrtShell->Undo();
244 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
245 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
246 CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
249 // now try the same with redlining enabled - should be the same result
250 dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
251 dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
253 pWrtShell->Down(false);
254 pWrtShell->SttPara(/*bSelect=*/false);
255 pWrtShell->EndPara(/*bSelect=*/true);
256 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
258 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
259 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
260 // problem was that this deleted all at-char flys, even at the start/end
261 CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
263 pWrtShell->Up(false);
264 dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
266 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() != nullptr);
267 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs()->size());
268 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
269 CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
271 pWrtShell->Undo();
272 pWrtShell->Undo();
274 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
275 CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
276 CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
280 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf149548)
282 createSwDoc("forum-mso-en-13192-min.docx");
283 SwDoc* pDoc = getSwDoc();
285 for (SwRangeRedline const*const pRedline : pDoc->getIDocumentRedlineAccess().GetRedlineTable())
287 if (pRedline->GetType() == RedlineType::Delete)
289 int nLevel(0);
290 for (SwNodeIndex index = pRedline->Start()->nNode; index <= pRedline->End()->nNode; ++index)
292 switch (index.GetNode().GetNodeType())
294 case SwNodeType::Start:
295 case SwNodeType::Table:
296 case SwNodeType::Section:
297 ++nLevel;
298 break;
299 case SwNodeType::End:
300 CPPUNIT_ASSERT_MESSAGE("bad overlapping redline", nLevel != 0);
301 --nLevel;
302 break;
303 default:
304 break;
307 CPPUNIT_ASSERT_EQUAL_MESSAGE("bad overlapping redline", int(0), nLevel);
311 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
313 dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
315 // this was a use-after-free on nodes deleted by Copy
316 dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
319 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testPasteTableAtFlyAnchor)
321 createSwDoc();
322 SwDoc* pDoc = getSwDoc();
323 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
325 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
326 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
327 SfxItemSet flySet(pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>);
328 flySet.Put(anchor);
329 SwFlyFrameFormat const* pFly = dynamic_cast<SwFlyFrameFormat const*>(
330 pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true));
331 CPPUNIT_ASSERT(pFly != nullptr);
332 CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
333 pWrtShell->SelFlyGrabCursor();
334 pWrtShell->GetDrawView()->UnmarkAll();
335 CPPUNIT_ASSERT(pWrtShell->GetCurrFlyFrame() != nullptr);
337 // insert table in fly
338 SwInsertTableOptions tableOpt(SwInsertTableFlags::DefaultBorder, 0);
339 pWrtShell->InsertTable(tableOpt, 2, 2);
341 // select table
342 pWrtShell->SelAll();
344 dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
346 // move cursor back to body
347 pWrtShell->ClearMark();
348 pWrtShell->SttEndDoc(/*bStt=*/true);
349 CPPUNIT_ASSERT(!pWrtShell->GetCurrFlyFrame());
351 dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
353 pWrtShell->SttEndDoc(/*bStt=*/true);
354 CPPUNIT_ASSERT(pWrtShell->IsCursorInTable());
355 CPPUNIT_ASSERT(!pFly->GetAnchor().GetContentAnchor()->GetNode().FindTableNode());
357 pWrtShell->Undo();
359 pWrtShell->SttEndDoc(/*bStt=*/true);
360 CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable());
361 CPPUNIT_ASSERT(!pFly->GetAnchor().GetContentAnchor()->GetNode().FindTableNode());
363 // the problem was that Redo moved the fly anchor into the first table cell
364 pWrtShell->Redo();
366 pWrtShell->SttEndDoc(/*bStt=*/true);
367 CPPUNIT_ASSERT(pWrtShell->IsCursorInTable());
368 CPPUNIT_ASSERT(!pFly->GetAnchor().GetContentAnchor()->GetNode().FindTableNode());
370 pWrtShell->Undo();
372 pWrtShell->SttEndDoc(/*bStt=*/true);
373 CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable());
374 CPPUNIT_ASSERT(!pFly->GetAnchor().GetContentAnchor()->GetNode().FindTableNode());
377 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCopyPastePageBreak)
379 createSwDoc("pagebreak-source.fodt");
381 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
382 CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
384 pWrtShell->SelAll();
385 dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
387 createSwDoc("pagebreak-target.fodt");
388 SwDoc* pDoc = getSwDoc();
389 pWrtShell = getSwDocShell()->GetWrtShell();
391 CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
392 CPPUNIT_ASSERT_EQUAL(u"WithMargin"_ustr, getProperty<OUString>(getParagraph(1), u"PageDescName"_ustr));
393 CPPUNIT_ASSERT_EQUAL(u"TargetSection"_ustr, pWrtShell->GetCurrSection()->GetSectionName());
394 // page style WithMargin is used
395 CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
397 dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
399 CPPUNIT_ASSERT_EQUAL(2, getParagraphs());
400 CPPUNIT_ASSERT_EQUAL(u"WithMargin"_ustr, getProperty<OUString>(getParagraph(1), u"PageDescName"_ustr));
401 CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetSections().size());
402 CPPUNIT_ASSERT_EQUAL(u"SourceSection"_ustr, pWrtShell->GetCurrSection()->GetSectionName());
403 // the problem was that there was a page break now
404 CPPUNIT_ASSERT_EQUAL(1, getPages());
405 // page style WithMargin is used
406 CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
408 pWrtShell->Undo();
409 CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
410 CPPUNIT_ASSERT_EQUAL(u"WithMargin"_ustr, getProperty<OUString>(getParagraph(1), u"PageDescName"_ustr));
411 CPPUNIT_ASSERT_EQUAL(u"TargetSection"_ustr, pWrtShell->GetCurrSection()->GetSectionName());
412 CPPUNIT_ASSERT_EQUAL(1, getPages());
413 // page style WithMargin is used
414 CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
416 pWrtShell->Redo();
417 CPPUNIT_ASSERT_EQUAL(2, getParagraphs());
418 CPPUNIT_ASSERT_EQUAL(u"WithMargin"_ustr, getProperty<OUString>(getParagraph(1), u"PageDescName"_ustr));
419 CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetSections().size());
420 CPPUNIT_ASSERT_EQUAL(u"SourceSection"_ustr, pWrtShell->GetCurrSection()->GetSectionName());
421 CPPUNIT_ASSERT_EQUAL(1, getPages());
422 // page style WithMargin is used
423 CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
425 pWrtShell->Undo();
426 CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
427 CPPUNIT_ASSERT_EQUAL(u"WithMargin"_ustr, getProperty<OUString>(getParagraph(1), u"PageDescName"_ustr));
428 CPPUNIT_ASSERT_EQUAL(u"TargetSection"_ustr, pWrtShell->GetCurrSection()->GetSectionName());
429 CPPUNIT_ASSERT_EQUAL(1, getPages());
430 // page style WithMargin is used
431 CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
434 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testBookmarkCopy)
436 createSwDoc();
437 SwDoc* pDoc = getSwDoc();
439 // add text and bookmark
440 IDocumentMarkAccess & rIDMA(*pDoc->getIDocumentMarkAccess());
441 IDocumentContentOperations & rIDCO(pDoc->getIDocumentContentOperations());
442 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
443 SwCursor aPaM(SwPosition(aIdx), nullptr);
444 rIDCO.InsertString(aPaM, u"foo"_ustr);
445 rIDCO.SplitNode(*aPaM.GetPoint(), false);
446 rIDCO.InsertString(aPaM, u"bar"_ustr);
447 aPaM.SetMark();
448 aPaM.MovePara(GoCurrPara, fnParaStart);
449 rIDMA.makeMark(aPaM, u"Mark"_ustr, IDocumentMarkAccess::MarkType::BOOKMARK,
450 ::sw::mark::InsertMode::New);
451 aPaM.Exchange();
452 aPaM.DeleteMark();
453 rIDCO.SplitNode(*aPaM.GetPoint(), false);
454 rIDCO.InsertString(aPaM, u"baz"_ustr);
456 // copy range
457 rIDCO.SplitNode(*aPaM.GetPoint(), false);
458 SwPosition target(*aPaM.GetPoint());
459 aPaM.Move(fnMoveBackward, GoInContent);
460 aPaM.SetMark();
461 aPaM.SttEndDoc(true/*start*/);
462 aPaM.Move(fnMoveForward, GoInContent); // partially select 1st para
464 rIDCO.CopyRange(aPaM, target, SwCopyFlags::CheckPosInFly);
466 // check bookmark was copied to correct position
467 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), rIDMA.getBookmarksCount());
468 for (auto it(rIDMA.getBookmarksBegin()); it != rIDMA.getBookmarksEnd(); ++it)
470 OUString markText(SwPaM((*it)->GetMarkPos(), (*it)->GetOtherMarkPos()).GetText());
471 CPPUNIT_ASSERT_EQUAL(u"bar"_ustr, markText);
474 // copy 2nd time, such that bCanMoveBack is false in CopyImpl
475 SwPaM aCopyPaM(*aPaM.GetMark(), *aPaM.GetPoint());
476 aPaM.SttEndDoc(true/*start*/);
477 rIDCO.SplitNode(*aPaM.GetPoint(), false);
478 aPaM.SttEndDoc(true/*start*/);
480 rIDCO.CopyRange(aCopyPaM, *aPaM.GetPoint(), SwCopyFlags::CheckPosInFly);
482 // check bookmark was copied to correct position
483 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), rIDMA.getBookmarksCount());
484 for (auto it(rIDMA.getBookmarksBegin()); it != rIDMA.getBookmarksEnd(); ++it)
486 OUString markText(SwPaM((*it)->GetMarkPos(), (*it)->GetOtherMarkPos()).GetText());
487 CPPUNIT_ASSERT_EQUAL(u"bar"_ustr, markText);
491 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFormulaNumberWithGroupSeparator)
493 createSwDoc("tdf125154.odt");
494 dispatchCommand(mxComponent, u".uno:UpdateAll"_ustr, {});
495 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
496 pWrtShell->SttEndDoc(true);
497 SwField const* pField;
499 pField = pWrtShell->GetCurField();
500 CPPUNIT_ASSERT_EQUAL(u"1000"_ustr, pField->GetFormula());
501 CPPUNIT_ASSERT_EQUAL(u"1.000"_ustr, pField->ExpandField(true, nullptr));
502 pWrtShell->GoNextCell();
503 CPPUNIT_ASSERT_EQUAL(u"10000"_ustr, pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
504 pWrtShell->GoNextCell();
505 pField = pWrtShell->GetCurField();
506 CPPUNIT_ASSERT_EQUAL(u"test"_ustr, pField->GetFormula());
507 CPPUNIT_ASSERT_EQUAL(u"1.000"_ustr, pField->ExpandField(true, nullptr));
508 pWrtShell->GoNextCell();
509 // the problem was that this was 0
510 CPPUNIT_ASSERT_EQUAL(u"10000"_ustr, pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
511 pWrtShell->Down(false);
512 pWrtShell->SttPara(false);
513 pField = pWrtShell->GetCurField();
514 CPPUNIT_ASSERT_EQUAL(u"1000*10%"_ustr, pField->GetFormula());
515 CPPUNIT_ASSERT_EQUAL(u"100"_ustr, pField->ExpandField(true, nullptr));
516 pWrtShell->Down(false);
517 pField = pWrtShell->GetCurField();
518 CPPUNIT_ASSERT_EQUAL(u"5.000*10%"_ustr, pField->GetFormula());
519 // the problem was that this was 0
520 CPPUNIT_ASSERT_EQUAL(u"500"_ustr, pField->ExpandField(true, nullptr));
521 pWrtShell->Down(false);
522 pField = pWrtShell->GetCurField();
523 CPPUNIT_ASSERT_EQUAL(u"5.000*10%"_ustr, pField->GetFormula());
524 // the problem was that this was
525 CPPUNIT_ASSERT_EQUAL(u"500"_ustr, pField->ExpandField(true, nullptr));
526 pWrtShell->Down(false);
527 pField = pWrtShell->GetCurField();
528 CPPUNIT_ASSERT_EQUAL(u"5000*10%"_ustr, pField->GetFormula());
529 CPPUNIT_ASSERT_EQUAL(u"500"_ustr, pField->ExpandField(true, nullptr));
530 pWrtShell->Down(false);
531 CPPUNIT_ASSERT_EQUAL(u"-100,00 €"_ustr, pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
532 pWrtShell->GoNextCell();
533 // tdf#42518 the problem was that this was 1.900,00 €
534 CPPUNIT_ASSERT_EQUAL(u"** Expression is faulty **"_ustr, pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
537 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testInsertFileInInputFieldException)
539 createSwDoc();
540 uno::Reference<text::XTextDocument> const xTextDoc(mxComponent, uno::UNO_QUERY);
541 uno::Reference<text::XText> const xBody(xTextDoc->getText());
542 uno::Reference<lang::XMultiServiceFactory> const xFactory(mxComponent, uno::UNO_QUERY);
543 uno::Reference<text::XTextCursor> const xCursor(xBody->createTextCursor());
544 uno::Reference<document::XDocumentInsertable> const xInsertable(xCursor, uno::UNO_QUERY);
545 uno::Reference<text::XTextContent> const xContent(
546 xFactory->createInstance(u"com.sun.star.text.textfield.Input"_ustr), uno::UNO_QUERY);
547 xBody->insertTextContent(xCursor, xContent, false);
548 xCursor->goLeft(1, false);
549 // try to insert some random file
550 // inserting even asserts in debug builds - document model goes invalid with input field split across 2 nodes
551 CPPUNIT_ASSERT_THROW(xInsertable->insertDocumentFromURL(createFileURL(u"fdo75110.odt"), {}), uno::RuntimeException);
554 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf67238)
556 //create a new writer document
557 createSwDoc();
558 SwDoc* pDoc = getSwDoc();
559 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
560 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
561 //insert a 3X3 table in the newly created document
562 SwInsertTableOptions TableOpt(SwInsertTableFlags::DefaultBorder, 0);
563 const SwTable& rTable = pWrtShell->InsertTable(TableOpt, 3, 3);
564 //checking for the rows and columns
565 uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
566 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getRows()->getCount());
567 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getColumns()->getCount());
568 //selecting the table
569 pWrtShell->StartOfSection();
570 pWrtShell->SelTable();
571 //making the table protected
572 pWrtShell->ProtectCells();
573 //checking each cell's protection, it should be protected
574 CPPUNIT_ASSERT(((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
575 CPPUNIT_ASSERT(((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
576 CPPUNIT_ASSERT(((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
577 CPPUNIT_ASSERT(((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
578 CPPUNIT_ASSERT(((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
579 CPPUNIT_ASSERT(((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
580 CPPUNIT_ASSERT(((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
581 CPPUNIT_ASSERT(((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
582 CPPUNIT_ASSERT(((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
583 //undo the changes, make cells [un]protected
584 rUndoManager.Undo();
585 //checking each cell's protection, it should be [un]protected
586 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
587 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
588 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
589 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
590 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
591 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
592 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
593 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
594 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
595 //redo the changes, make cells protected
596 rUndoManager.Redo();
597 //checking each cell's protection, it should be protected
598 CPPUNIT_ASSERT(((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
599 CPPUNIT_ASSERT(((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
600 CPPUNIT_ASSERT(((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
601 CPPUNIT_ASSERT(((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
602 CPPUNIT_ASSERT(((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
603 CPPUNIT_ASSERT(((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
604 CPPUNIT_ASSERT(((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
605 CPPUNIT_ASSERT(((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
606 CPPUNIT_ASSERT(((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
607 //moving the cursor to the starting of the document
608 pWrtShell->StartOfSection();
609 //making the table [un]protected
610 pWrtShell->SelTable();
611 pWrtShell->UnProtectCells();
612 //checking each cell's protection, it should be [un]protected
613 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
614 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
615 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
616 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
617 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
618 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
619 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
620 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
621 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
622 //undo the changes, make cells protected
623 rUndoManager.Undo();
624 //checking each cell's protection, it should be protected
625 CPPUNIT_ASSERT(((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
626 CPPUNIT_ASSERT(((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
627 CPPUNIT_ASSERT(((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
628 CPPUNIT_ASSERT(((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
629 CPPUNIT_ASSERT(((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
630 CPPUNIT_ASSERT(((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
631 CPPUNIT_ASSERT(((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
632 CPPUNIT_ASSERT(((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
633 CPPUNIT_ASSERT(((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
634 //redo the changes, make cells [un]protected
635 rUndoManager.Redo();
636 //checking each cell's protection, it should be [un]protected
637 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
638 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
639 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
640 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
641 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
642 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
643 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
644 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
645 CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
648 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf155685)
650 createSwDoc("table-at-end-of-cell.fodt");
651 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
652 pWrtShell->GoNextCell();
653 pWrtShell->GoNextCell();
654 pWrtShell->GoNextCell();
655 pWrtShell->SelAll();
656 pWrtShell->Delete();
657 // this crashed
658 pWrtShell->Undo();
659 pWrtShell->Undo();
660 pWrtShell->Redo();
661 // this crashed
662 pWrtShell->Redo();
665 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf147220)
667 createSwDoc();
668 SwDoc* pDoc = getSwDoc();
669 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
671 pWrtShell->Insert(u"él"_ustr);
673 // hide and enable
674 dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
675 dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
676 CPPUNIT_ASSERT(pDoc->getIDocumentRedlineAccess().IsRedlineOn());
677 CPPUNIT_ASSERT(
678 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
679 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
681 pWrtShell->GoStartSentence();
682 pWrtShell->SetMark();
683 pWrtShell->GoEndSentence();
685 // this did not remove the original text from the layout
686 pWrtShell->Replace(u"Él"_ustr, false);
688 // currently the deleted text is before the replacement text, not sure if
689 // that is really required
690 CPPUNIT_ASSERT_EQUAL(u"élÉl"_ustr,
691 pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode()->GetText());
692 CPPUNIT_ASSERT_EQUAL(u"Él"_ustr,
693 static_cast<SwTextFrame const*>(pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode()->getLayoutFrame(nullptr))->GetText());
695 SwRedlineTable const& rRedlines(pDoc->getIDocumentRedlineAccess().GetRedlineTable());
696 CPPUNIT_ASSERT_EQUAL(SwRedlineTable::size_type(2), rRedlines.size());
697 CPPUNIT_ASSERT_EQUAL(RedlineType::Delete, rRedlines[0]->GetType());
698 CPPUNIT_ASSERT_EQUAL(u"él"_ustr, rRedlines[0]->GetText());
699 CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rRedlines[1]->GetType());
700 CPPUNIT_ASSERT_EQUAL(u"Él"_ustr, rRedlines[1]->GetText());
703 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf135978)
705 createSwDoc();
706 SwDoc* pDoc = getSwDoc();
707 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
709 pWrtShell->Insert(u"foobar"_ustr);
710 pWrtShell->SplitNode();
711 pWrtShell->Insert(u"bazquux"_ustr);
713 CPPUNIT_ASSERT(pWrtShell->IsEndOfDoc());
715 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
716 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
717 SfxItemSet flySet(pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>);
718 flySet.Put(anchor);
719 SwFlyFrameFormat const* pFly = dynamic_cast<SwFlyFrameFormat const*>(
720 pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true));
721 CPPUNIT_ASSERT(pFly != nullptr);
722 CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
723 // move cursor back to body
724 pWrtShell->SttEndDoc(/*bStt=*/false);
726 // hide and enable
727 dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
728 dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
730 CPPUNIT_ASSERT(pDoc->getIDocumentRedlineAccess().IsRedlineOn());
731 CPPUNIT_ASSERT(
732 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
733 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
735 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
736 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 6, /*bBasicCall=*/false);
737 pWrtShell->Delete();
739 // now split
740 pWrtShell->SttEndDoc(/*bStt=*/true);
741 pWrtShell->SplitNode();
742 CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
744 // the problem was that undo removed the fly frame from the layout
745 pWrtShell->Undo();
746 CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
748 pWrtShell->Redo();
749 CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
751 pWrtShell->Undo();
752 CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
755 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo75110)
757 createSwDoc("fdo75110.odt");
758 SwDoc* pDoc = getSwDoc();
759 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
761 pWrtShell->SelAll();
762 // The problem was that SwEditShell::DeleteSel() what this Delete() invokes took the wrong selection...
763 pWrtShell->Delete();
764 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
765 // ... so this Undo() call resulted in a crash.
766 rUndoManager.Undo();
769 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo75898)
771 createSwDoc("fdo75898.odt");
772 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
773 pWrtShell->SelAll();
774 pWrtShell->InsertRow(1, true);
775 pWrtShell->InsertRow(1, true);
777 // Now check if the table has 3 lines.
778 SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
779 SwTableNode* pTableNode = pShellCursor->Start()->GetNode().FindTableNode();
780 // This was 1, when doing the same using the UI, Writer even crashed.
781 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pTableNode->GetTable().GetTabLines().size());
784 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testReplaceBackward)
786 //Regression test of fdo#70143
787 //EDITING: undo search&replace corrupt text when searching backward
788 createSwDoc();
789 SwDoc* pDoc = getSwDoc();
791 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
793 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
794 SwPaM aPaM(aIdx);
796 pDoc->getIDocumentContentOperations().InsertString(aPaM, u"toto titi tutu"_ustr);
797 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
798 lcl_selectCharacters(aPaM, 9, 5);
800 pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, u"toto"_ustr, false);
802 CPPUNIT_ASSERT_EQUAL(EXPECTED_REPLACE_CONTENT, pTextNode->GetText());
804 rUndoManager.Undo();
806 CPPUNIT_ASSERT_EQUAL(ORIGINAL_REPLACE_CONTENT, pTextNode->GetText());
809 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo69893)
811 createSwDoc("fdo69893.odt");
812 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
814 pWrtShell->SelAll(); // A1 is empty -> selects the whole table.
815 pWrtShell->SelAll(); // Selects the whole document.
817 SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
818 SwTextNode& rEnd = dynamic_cast<SwTextNode&>(pShellCursor->End()->GetNode());
819 // Selection did not include the para after table, this was "B1".
820 CPPUNIT_ASSERT_EQUAL(u"Para after table."_ustr, rEnd.GetText());
823 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo70807)
825 createSwDoc("fdo70807.odt");
827 uno::Reference<container::XIndexAccess> xStylesIter(getStyles(u"PageStyles"_ustr), uno::UNO_QUERY);
829 for (sal_Int32 i = 0; i < xStylesIter->getCount(); ++i)
831 uno::Reference<style::XStyle> xStyle(xStylesIter->getByIndex(i), uno::UNO_QUERY);
833 bool expectedUsedStyle = false;
834 bool expectedUserDefined = false;
836 OUString styleName(xStyle->getName());
838 // just these styles are user defined styles
839 if (styleName == "pagestyle1" || styleName == "pagestyle2")
840 expectedUserDefined = true;
842 // just these styles are used in the document
843 if (styleName == "Right Page" || styleName == "pagestyle1" || styleName == "pagestyle2")
844 expectedUsedStyle = true;
846 CPPUNIT_ASSERT_EQUAL(expectedUserDefined, bool(xStyle->isUserDefined()));
847 CPPUNIT_ASSERT_EQUAL(expectedUsedStyle, bool(xStyle->isInUse()));
851 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testImportRTF)
853 // Insert "foobar" and position the cursor between "foo" and "bar".
854 createSwDoc();
855 SwDoc* pDoc = getSwDoc();
856 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
857 pWrtShell->Insert(u"foobar"_ustr);
858 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 3, /*bBasicCall=*/false);
860 // Insert the RTF at the cursor position.
861 OString aData = "{\\rtf1 Hello world!\\par}"_ostr;
862 SvMemoryStream aStream(const_cast<char*>(aData.getStr()), aData.getLength(), StreamMode::READ);
863 SwReader aReader(aStream, OUString(), OUString(), *pWrtShell->GetCursor());
864 Reader* pRTFReader = SwReaderWriter::GetRtfReader();
865 CPPUNIT_ASSERT(pRTFReader != nullptr);
866 CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, aReader.Read(*pRTFReader).GetCode());
868 SwNodeOffset nIndex = pWrtShell->GetCursor()->GetPointNode().GetIndex();
869 CPPUNIT_ASSERT_EQUAL(u"fooHello world!"_ustr, pDoc->GetNodes()[nIndex - 1]->GetTextNode()->GetText());
870 CPPUNIT_ASSERT_EQUAL(u"bar"_ustr, pDoc->GetNodes()[nIndex]->GetTextNode()->GetText());
873 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testExportRTF)
875 // Insert "aaabbbccc" and select "bbb".
876 createSwDoc();
877 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
878 pWrtShell->Insert(u"aaabbbccc"_ustr);
879 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 3, /*bBasicCall=*/false);
880 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 3, /*bBasicCall=*/false);
882 // Create the clipboard document.
883 rtl::Reference<SwDoc> xClpDoc(new SwDoc());
884 xClpDoc->SetClipBoard(true);
885 pWrtShell->Copy(*xClpDoc);
887 // And finally export it as RTF.
888 WriterRef xWrt;
889 SwReaderWriter::GetWriter(u"RTF", OUString(), xWrt);
890 SvMemoryStream aStream;
891 SwWriter aWrt(aStream, *xClpDoc);
892 aWrt.Write(xWrt);
894 OString aData(static_cast<const char*>(aStream.GetData()), aStream.GetSize());
896 //Amusingly eventually there was a commit id with "ccc" in it, and so the rtf contained
897 //{\*\generator LibreOfficeDev/4.4.0.0.alpha0$Linux_X86_64 LibreOffice_project/f70664ccc6837f2cc21a29bb4f44e41e100efe6b}
898 //so the test fell over. so strip the generator tag
899 sal_Int32 nGeneratorStart = aData.indexOf("{\\*\\generator ");
900 CPPUNIT_ASSERT(nGeneratorStart != -1);
901 sal_Int32 nGeneratorEnd = aData.indexOf('}', nGeneratorStart + 1);
902 CPPUNIT_ASSERT(nGeneratorEnd != -1);
903 aData = aData.replaceAt(nGeneratorStart, nGeneratorEnd-nGeneratorStart+1, "");
905 CPPUNIT_ASSERT(aData.startsWith("{\\rtf1"));
906 CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aData.indexOf("aaa"));
907 CPPUNIT_ASSERT(aData.indexOf("bbb") != -1);
908 CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aData.indexOf("ccc"));
909 // Ensure there's no extra newline
910 CPPUNIT_ASSERT(aData.endsWith("bbb}" SAL_NEWLINE_STRING "}"));
913 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOCXAutoTextEmpty)
915 // file contains normal content but no AutoText
916 std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-empty.dotx", true);
917 CPPUNIT_ASSERT(pGlossary != nullptr);
920 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOCXAutoTextMultiple)
922 // file contains three AutoText entries
923 std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-multiple.dotx");
925 // check entries count
926 CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), pGlossary->GetCount());
928 // check names of entries, sorted order
929 CPPUNIT_ASSERT_EQUAL(u"Anothercomplex"_ustr, pGlossary->GetLongName(0));
930 CPPUNIT_ASSERT_EQUAL(u"Multiple"_ustr, pGlossary->GetLongName(1));
931 CPPUNIT_ASSERT_EQUAL(u"Second Autotext"_ustr, pGlossary->GetLongName(2));
933 // check if previously loaded content is correct (eg. doesn't contain title)
934 SwDoc* pDoc = pGlossary->GetDoc();
935 CPPUNIT_ASSERT(pDoc != nullptr);
937 SwNodeIndex aDocEnd(pDoc->GetNodes().GetEndOfContent());
938 SwNodeIndex aStart(*aDocEnd.GetNode().StartOfSectionNode(), 1);
940 CPPUNIT_ASSERT(aStart < aDocEnd);
942 // first line
943 SwNode& rNode = aStart.GetNode();
944 CPPUNIT_ASSERT(rNode.IsTextNode());
945 SwTextNode& rTextNode = *rNode.GetTextNode();
946 CPPUNIT_ASSERT_EQUAL(u"Another "_ustr, rTextNode.GetText());
948 // Make sure that autotext does not set a custom page style, leading to an unexpected page break
949 // on insertion.
950 // Without the accompanying fix in place, this test would have failed: the text node had an
951 // attribute set containing a page style item.
952 CPPUNIT_ASSERT(!rTextNode.HasSwAttrSet() || !rTextNode.GetSwAttrSet().HasItem(RES_PAGEDESC));
954 // last line
955 SwNodeIndex aLast(*aDocEnd.GetNode().EndOfSectionNode(), -1);
956 SwNode& rLastNode = aLast.GetNode();
957 CPPUNIT_ASSERT_EQUAL(u"complex"_ustr, rLastNode.GetTextNode()->GetText());
960 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOTMAutoText)
962 // this is dotm file difference is that in the dotm
963 // there are no empty paragraphs at the end of each entry
964 std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-dotm.dotm");
966 SwDoc* pDoc = pGlossary->GetDoc();
967 CPPUNIT_ASSERT(pDoc != nullptr);
969 // check if content is correct
970 SwNodeIndex aDocEnd(pDoc->GetNodes().GetEndOfContent());
971 SwNodeIndex aStart(*aDocEnd.GetNode().StartOfSectionNode(), 1);
972 SwNode& rNode = aStart.GetNode();
973 CPPUNIT_ASSERT_EQUAL(u"paragraph"_ustr, rNode.GetTextNode()->GetText());
976 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOCXAutoTextGallery)
978 // this file contains one AutoText entry and other
979 // entries which are not AutoText (have different "gallery" value)
980 std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-gallery.dotx");
982 SwDoc* pDoc = pGlossary->GetDoc();
983 CPPUNIT_ASSERT(pDoc != nullptr);
985 // check entries count
986 CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), pGlossary->GetCount());
988 // check entry name (if not contains gallery type)
989 CPPUNIT_ASSERT_EQUAL(u"Multiple"_ustr, pGlossary->GetLongName(0));
992 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testWatermarkDOCX)
994 createSwDoc("watermark.docx");
995 SwDocShell* pDocShell = getSwDocShell();
996 SfxPoolItemHolder aResult;
997 SfxItemState eState = pDocShell->GetViewShell()->GetViewFrame().GetDispatcher()->QueryState(SID_WATERMARK, aResult);
998 const SfxWatermarkItem* pWatermark(static_cast<const SfxWatermarkItem*>(aResult.getItem()));
1000 CPPUNIT_ASSERT(eState >= SfxItemState::DEFAULT);
1001 CPPUNIT_ASSERT(pWatermark);
1002 CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(SID_WATERMARK), pWatermark->Which());
1004 CPPUNIT_ASSERT_EQUAL(u"CustomWatermark"_ustr, pWatermark->GetText());
1005 CPPUNIT_ASSERT_EQUAL(u"DejaVu Sans Light"_ustr, pWatermark->GetFont());
1006 CPPUNIT_ASSERT_EQUAL(sal_Int16(45), pWatermark->GetAngle());
1007 CPPUNIT_ASSERT_EQUAL(Color(0x548dd4), pWatermark->GetColor());
1008 CPPUNIT_ASSERT_EQUAL(sal_Int16(50), pWatermark->GetTransparency());
1011 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testWatermarkPosition)
1013 // tdf#108494 Watermark inserted in the document with page break was outside the first page
1014 const int aPagesInDocument = 2;
1015 const int aAdditionalPagesCount[] = { 0, 0, 1, 1, 5, 5, 20, 20 };
1016 const bool aChangeHeader[] = { true, false, true, false, true, false, true, false };
1018 for (tools::ULong i = 0; i < sizeof(aAdditionalPagesCount) / sizeof(int); ++i)
1020 int aPages = aPagesInDocument + aAdditionalPagesCount[i];
1022 // Empty document with one Page Break
1023 createSwDoc("watermark-position.odt");
1024 SwDoc* pDoc = getSwDoc();
1025 SwEditShell* pEditShell = pDoc->GetEditShell();
1026 CPPUNIT_ASSERT(pEditShell);
1027 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1028 uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
1029 uno::UNO_QUERY);
1030 uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
1032 // 1. Add additional page breaks
1033 for (int j = 0; j < aAdditionalPagesCount[i]; ++j)
1034 pWrtShell->InsertPageBreak();
1036 // 2. Change header state (On, Off, On)
1037 if (aChangeHeader[i])
1039 SwPageDesc aDesc(pDoc->GetPageDesc(0));
1040 SwFrameFormat& rMaster = aDesc.GetMaster();
1041 rMaster.SetFormatAttr(SwFormatHeader(true));
1042 pDoc->ChgPageDesc(0, aDesc);
1044 aDesc = pDoc->GetPageDesc(0);
1045 SwFrameFormat& rMaster2 = aDesc.GetMaster();
1046 rMaster2.SetFormatAttr(SwFormatHeader(false));
1047 pDoc->ChgPageDesc(0, aDesc);
1049 aDesc = pDoc->GetPageDesc(0);
1050 SwFrameFormat& rMaster3 = aDesc.GetMaster();
1051 rMaster3.SetFormatAttr(SwFormatHeader(true));
1052 pDoc->ChgPageDesc(0, aDesc);
1055 // 3. Insert Watermark
1056 SfxWatermarkItem aWatermark;
1057 aWatermark.SetText(u"Watermark"_ustr);
1058 aWatermark.SetFont(u"DejaVu Sans"_ustr);
1060 pEditShell->SetWatermark(aWatermark);
1062 uno::Reference<css::drawing::XShape> xShape = getShape(1);
1063 CPPUNIT_ASSERT(xShape.is());
1065 SdrPage* pPage = pWrtShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1067 // Get Watermark object
1068 SdrObject* pObject = pPage->GetObj(0);
1069 pObject->RecalcBoundRect();
1070 const tools::Rectangle& rRect = pObject->GetSnapRect();
1071 Size rSize = pPage->GetSize();
1073 // Page break, calculate height of a page
1074 const int nPageHeight = rSize.getHeight() / aPages;
1076 std::stringstream aMessage;
1077 aMessage << "Case: " << i << ", nPageHeight = " << nPageHeight << ", rRect.Bottom = " << rRect.Bottom();
1079 // Check if Watermark is inside a page
1080 CPPUNIT_ASSERT_MESSAGE(aMessage.str(), nPageHeight >= rRect.Bottom());
1082 // Check if Watermark is centered
1083 CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, getProperty<sal_Int16>(xShape, u"HoriOrient"_ustr));
1084 CPPUNIT_ASSERT_EQUAL(text::VertOrientation::CENTER, getProperty<sal_Int16>(xShape, u"VertOrient"_ustr));
1088 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo74981)
1090 // create a document with an input field
1091 createSwDoc();
1092 SwDoc* pDoc = getSwDoc();
1093 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1094 SwInputField aField(static_cast<SwInputFieldType*>(pWrtShell->GetFieldType(0, SwFieldIds::Input)), u"foo"_ustr, u"bar"_ustr, 0, 0);
1095 pWrtShell->InsertField2(aField);
1098 // expect hints
1099 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
1100 SwTextNode* pTextNode = aIdx.GetNode().GetTextNode();
1101 CPPUNIT_ASSERT(pTextNode->HasHints());
1104 // go to the begin of the paragraph and split this node
1105 pWrtShell->Left(SwCursorSkipMode::Chars, false, 100, false);
1106 pWrtShell->SplitNode();
1109 // expect only the second paragraph to have hints
1110 SwNodeIndex aIdx(SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1));
1111 SwTextNode* pTextNode = aIdx.GetNode().GetTextNode();
1112 CPPUNIT_ASSERT(pTextNode->HasHints());
1113 --aIdx;
1114 pTextNode = aIdx.GetNode().GetTextNode();
1115 CPPUNIT_ASSERT(!pTextNode->HasHints());
1119 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf98512)
1121 createSwDoc();
1122 SwDoc* pDoc = getSwDoc();
1123 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1124 SwInputFieldType *const pType(static_cast<SwInputFieldType*>(
1125 pWrtShell->GetFieldType(0, SwFieldIds::Input)));
1126 SwInputField aField1(pType, u"foo"_ustr, u"bar"_ustr, INP_TXT, 0);
1127 pWrtShell->InsertField2(aField1);
1128 pWrtShell->SttEndDoc(/*bStt=*/true);
1129 SwInputField aField2(pType, u"baz"_ustr, u"quux"_ustr, INP_TXT, 0);
1130 pWrtShell->InsertField2(aField2);
1131 pWrtShell->SttEndDoc(/*bStt=*/true);
1132 pWrtShell->SetMark();
1133 pWrtShell->SttEndDoc(/*bStt=*/false);
1134 OUString const expected1(
1135 OUStringChar(CH_TXT_ATR_INPUTFIELDSTART) + "foo" + OUStringChar(CH_TXT_ATR_INPUTFIELDEND));
1136 OUString const expected2(
1137 OUStringChar(CH_TXT_ATR_INPUTFIELDSTART) + "baz" + OUStringChar(CH_TXT_ATR_INPUTFIELDEND)
1138 + expected1);
1139 CPPUNIT_ASSERT_EQUAL(expected2, pWrtShell->getShellCursor(false)->GetText());
1140 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1141 rUndoManager.Undo();
1142 pWrtShell->SttEndDoc(/*bStt=*/true);
1143 pWrtShell->SetMark();
1144 pWrtShell->SttEndDoc(/*bStt=*/false);
1145 CPPUNIT_ASSERT_EQUAL(expected1, pWrtShell->getShellCursor(false)->GetText());
1146 rUndoManager.Redo();
1147 pWrtShell->SttEndDoc(/*bStt=*/true);
1148 pWrtShell->SetMark();
1149 pWrtShell->SttEndDoc(/*bStt=*/false);
1150 CPPUNIT_ASSERT_EQUAL(expected2, pWrtShell->getShellCursor(false)->GetText());
1151 rUndoManager.Undo();
1152 pWrtShell->SttEndDoc(/*bStt=*/true);
1153 pWrtShell->SetMark();
1154 pWrtShell->SttEndDoc(/*bStt=*/false);
1155 CPPUNIT_ASSERT_EQUAL(expected1, pWrtShell->getShellCursor(false)->GetText());
1158 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxSelect)
1160 createSwDoc("shape-textbox.odt");
1161 SwDoc* pDoc = getSwDoc();
1162 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1163 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1164 SdrObject* pObject = pPage->GetObj(1);
1165 SwContact* pTextBox = static_cast<SwContact*>(pObject->GetUserCall());
1166 // First, make sure that pTextBox is a fly frame (textbox of a shape).
1167 CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_FLYFRMFMT), pTextBox->GetFormat()->Which());
1169 // Then select it.
1170 pWrtShell->SelectObj(Point(), 0, pObject);
1171 const SdrMarkList& rMarkList = pWrtShell->GetDrawView()->GetMarkedObjectList();
1172 SwDrawContact* pShape = static_cast<SwDrawContact*>(rMarkList.GetMark(0)->GetMarkedSdrObj()->GetUserCall());
1173 // And finally make sure the shape got selected, not just the textbox itself.
1174 CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_DRAWFRMFMT), pShape->GetFormat()->Which());
1177 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxDelete)
1179 createSwDoc("shape-textbox.odt");
1180 SwDoc* pDoc = getSwDoc();
1181 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1182 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1183 SdrObject* pObject = pPage->GetObj(0);
1184 pWrtShell->SelectObj(Point(), 0, pObject);
1185 size_t nActual = pPage->GetObjCount();
1186 // Two objects on the draw page: the shape and its textbox.
1187 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), nActual);
1189 pWrtShell->DelSelectedObj();
1190 nActual = pPage->GetObjCount();
1191 // Both (not only the shape) should be removed by now (the textbox wasn't removed, so this was 1).
1192 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), nActual);
1195 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testAnchorChangeSelection)
1197 createSwDoc("test_anchor_as_character.odt");
1198 SwDoc* pDoc = getSwDoc();
1199 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1200 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1201 SdrObject* pObject = pPage->GetObj(0);
1202 CPPUNIT_ASSERT(pObject);
1204 // Then select it.
1205 pWrtShell->SelectObj(Point(), 0, pObject);
1206 const SdrMarkList& rMarkList = pWrtShell->GetDrawView()->GetMarkedObjectList();
1207 CPPUNIT_ASSERT_EQUAL(pObject, rMarkList.GetMark(0)->GetMarkedSdrObj());
1209 pWrtShell->ChgAnchor(RndStdIds::FLY_AS_CHAR);
1211 // tdf#125039 shape must still be selected, extensions depend on that
1212 CPPUNIT_ASSERT_EQUAL(pObject, rMarkList.GetMark(0)->GetMarkedSdrObj());
1215 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCp1000071)
1217 createSwDoc("cp1000071.odt");
1218 SwDoc* pDoc = getSwDoc();
1219 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1221 const SwRedlineTable& rTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
1222 CPPUNIT_ASSERT_EQUAL( SwRedlineTable::size_type( 2 ), rTable.size());
1223 SwNodeOffset redlineStart0NodeIndex = rTable[ 0 ]->Start()->GetNodeIndex();
1224 sal_Int32 redlineStart0Index = rTable[ 0 ]->Start()->GetContentIndex();
1225 SwNodeOffset redlineEnd0NodeIndex = rTable[ 0 ]->End()->GetNodeIndex();
1226 sal_Int32 redlineEnd0Index = rTable[ 0 ]->End()->GetContentIndex();
1227 SwNodeOffset redlineStart1NodeIndex = rTable[ 1 ]->Start()->GetNodeIndex();
1228 sal_Int32 redlineStart1Index = rTable[ 1 ]->Start()->GetContentIndex();
1229 SwNodeOffset redlineEnd1NodeIndex = rTable[ 1 ]->End()->GetNodeIndex();
1230 sal_Int32 redlineEnd1Index = rTable[ 1 ]->End()->GetContentIndex();
1232 // Change the document layout to be 2 columns, and then undo.
1233 pWrtShell->SelAll();
1234 SwSectionData section(SectionType::Content, pWrtShell->GetUniqueSectionName());
1235 SfxItemSet set( getSwDocShell()->GetPool(), svl::Items<RES_COL, RES_COL> );
1236 SwFormatCol col;
1237 col.Init( 2, 0, 10000 );
1238 set.Put( col );
1239 pWrtShell->InsertSection( section, &set );
1240 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1241 rUndoManager.Undo();
1243 // Check that redlines are the same like at the beginning.
1244 CPPUNIT_ASSERT_EQUAL( SwRedlineTable::size_type( 2 ), rTable.size());
1245 CPPUNIT_ASSERT_EQUAL( redlineStart0NodeIndex, rTable[ 0 ]->Start()->GetNodeIndex());
1246 CPPUNIT_ASSERT_EQUAL( redlineStart0Index, rTable[ 0 ]->Start()->GetContentIndex());
1247 CPPUNIT_ASSERT_EQUAL( redlineEnd0NodeIndex, rTable[ 0 ]->End()->GetNodeIndex());
1248 CPPUNIT_ASSERT_EQUAL( redlineEnd0Index, rTable[ 0 ]->End()->GetContentIndex());
1249 CPPUNIT_ASSERT_EQUAL( redlineStart1NodeIndex, rTable[ 1 ]->Start()->GetNodeIndex());
1250 CPPUNIT_ASSERT_EQUAL( redlineStart1Index, rTable[ 1 ]->Start()->GetContentIndex());
1251 CPPUNIT_ASSERT_EQUAL( redlineEnd1NodeIndex, rTable[ 1 ]->End()->GetNodeIndex());
1252 CPPUNIT_ASSERT_EQUAL( redlineEnd1Index, rTable[ 1 ]->End()->GetContentIndex());
1255 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxVertadjust)
1257 createSwDoc("shape-textbox-vertadjust.odt");
1258 SwDoc* pDoc = getSwDoc();
1259 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1260 SdrObject* pObject = pPage->GetObj(1);
1261 SwFrameFormat* pFormat = static_cast<SwContact*>(pObject->GetUserCall())->GetFormat();
1262 // This was SDRTEXTVERTADJUST_TOP.
1263 CPPUNIT_ASSERT_EQUAL(SDRTEXTVERTADJUST_CENTER, pFormat->GetTextVertAdjust().GetValue());
1266 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxAutosize)
1268 createSwDoc("shape-textbox-autosize.odt");
1269 SwDoc* pDoc = getSwDoc();
1270 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1271 // 0-1 is the first UI-visible shape+textbox.
1272 SdrObject* pFirst = pPage->GetObj(0);
1273 CPPUNIT_ASSERT_EQUAL(u"1st"_ustr, pFirst->GetName());
1275 // 2-3 is the second UI-visible shape+textbox.
1276 SdrObject* pSecond = pPage->GetObj(2);
1277 CPPUNIT_ASSERT_EQUAL(u"2nd"_ustr, pSecond->GetName());
1279 // Shape -> textbox synchronization was missing, the second shape had the
1280 // same height as the first, even though the first contained 1 paragraph
1281 // and the other 2 ones.
1282 CPPUNIT_ASSERT(pFirst->GetSnapRect().getOpenHeight() < pSecond->GetSnapRect().getOpenHeight());
1285 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo82191)
1287 createSwDoc("fdo82191.odt");
1288 SwDoc* pDoc = getSwDoc();
1289 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1290 // Make sure we have a single draw shape.
1291 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), SwTextBoxHelper::getCount(pPage));
1293 SwDoc aClipboard;
1294 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1295 SdrObject* pObject = pPage->GetObj(0);
1296 // Select it, then copy and paste.
1297 pWrtShell->SelectObj(Point(), 0, pObject);
1298 pWrtShell->Copy(aClipboard);
1299 pWrtShell->Paste(aClipboard);
1301 // This was one: the textbox of the shape wasn't copied.
1302 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), SwTextBoxHelper::getCount(*pDoc));
1305 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCommentedWord)
1307 // This word is commented. <- string in document
1308 // 123456789 <- character positions
1309 createSwDoc("commented-word.odt");
1310 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1311 // Move the cursor into the second word.
1312 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 5, /*bBasicCall=*/false);
1313 // Select the word.
1314 pWrtShell->SelWrd();
1316 // Make sure that not only the word, but its comment anchor is also selected.
1317 SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
1318 // This was 9, only "word", not "word<anchor character>" was selected.
1319 CPPUNIT_ASSERT_EQUAL(sal_Int32(10), pShellCursor->End()->GetContentIndex());
1321 // Test that getAnchor() points to "word", not to an empty string.
1322 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
1323 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
1324 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
1325 uno::Reference<text::XTextContent> xField(xFields->nextElement(), uno::UNO_QUERY);
1326 CPPUNIT_ASSERT_EQUAL(u"word"_ustr, xField->getAnchor()->getString());
1329 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTextFieldGetAnchorGetTextInFooter)
1331 createSwDoc("textfield-getanchor-gettext-in-footer.odt");
1333 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
1334 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
1335 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
1336 uno::Reference<text::XTextContent> xField(xFields->nextElement(), uno::UNO_QUERY);
1338 OUString value = xField->getAnchor()->getText()->getString();
1339 CPPUNIT_ASSERT_EQUAL(u"userfield_in_footer"_ustr, value );
1342 // Tests that a blank document is still blank after conversion
1343 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionBlank)
1346 // Given
1347 createSwDoc();
1348 SwDoc* pDoc = getSwDoc();
1349 SwView* pView = getSwDocShell()->GetView();
1350 const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
1351 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
1352 SwPaM aPaM(aIdx);
1354 // When
1355 SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, nullptr,
1356 i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
1357 true, false, false );
1358 aWrap.Convert();
1360 // Then
1361 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
1362 CPPUNIT_ASSERT_EQUAL(OUString(), pTextNode->GetText());
1366 // Tests that non Chinese text is unchanged after conversion
1367 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionNonChineseText)
1370 // Given
1371 createSwDoc();
1372 SwDoc* pDoc = getSwDoc();
1373 SwView* pView = getSwDocShell()->GetView();
1374 const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
1375 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
1376 SwPaM aPaM(aIdx);
1377 pDoc->getIDocumentContentOperations().InsertString(aPaM, NON_CHINESE_CONTENT);
1379 // When
1380 SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, nullptr,
1381 i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
1382 true, false, false );
1383 aWrap.Convert();
1385 // Then
1386 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
1387 CPPUNIT_ASSERT_EQUAL(NON_CHINESE_CONTENT, pTextNode->GetText());
1391 // Tests conversion of traditional Chinese characters to simplified Chinese
1392 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionTraditionalToSimplified)
1395 // Given
1396 createSwDoc();
1397 SwDoc* pDoc = getSwDoc();
1398 SwView* pView = getSwDocShell()->GetView();
1399 const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
1400 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
1401 SwPaM aPaM(aIdx);
1402 pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(CHINESE_TRADITIONAL_CONTENT));
1404 // When
1405 SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, nullptr,
1406 i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
1407 true, false, false );
1408 aWrap.Convert();
1410 // Then
1411 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
1412 CPPUNIT_ASSERT_EQUAL(OUString(CHINESE_SIMPLIFIED_CONTENT), pTextNode->GetText());
1416 // Tests conversion of simplified Chinese characters to traditional Chinese
1417 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionSimplifiedToTraditional)
1420 // Given
1421 createSwDoc();
1422 SwDoc* pDoc = getSwDoc();
1423 SwView* pView = getSwDocShell()->GetView();
1424 const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
1425 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
1426 SwPaM aPaM(aIdx);
1427 pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(CHINESE_SIMPLIFIED_CONTENT));
1429 // When
1430 SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_SIMPLIFIED, LANGUAGE_CHINESE_TRADITIONAL, nullptr,
1431 i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
1432 true, false, false );
1433 aWrap.Convert();
1435 // Then
1436 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
1437 CPPUNIT_ASSERT_EQUAL(OUString(CHINESE_TRADITIONAL_CONTENT), pTextNode->GetText());
1441 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo85554)
1443 // Load the document, it contains one shape with a textbox.
1444 createSwDoc("fdo85554.odt");
1446 // Add a second shape to the document.
1447 uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
1448 uno::Reference<drawing::XShape> xShape(xFactory->createInstance(u"com.sun.star.drawing.RectangleShape"_ustr), uno::UNO_QUERY);
1449 xShape->setSize(awt::Size(10000, 10000));
1450 xShape->setPosition(awt::Point(1000, 1000));
1451 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
1452 uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
1453 xDrawPage->add(xShape);
1455 // Save it and load it back.
1456 saveAndReload(u"writer8"_ustr);
1458 // This was 1, we lost a shape on export.
1459 CPPUNIT_ASSERT_EQUAL(2, getShapes());
1462 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testMergeDoc)
1464 createSwDoc("merge-change1.odt");
1465 SwDoc* pDoc = getSwDoc();
1467 mxComponent2 = loadFromDesktop(
1468 createFileURL(u"merge-change2.odt"),
1469 u"com.sun.star.text.TextDocument"_ustr);
1470 auto pxDoc2Document(
1471 dynamic_cast<SwXTextDocument *>(mxComponent2.get()));
1472 CPPUNIT_ASSERT(pxDoc2Document);
1473 SwDoc* const pDoc2(pxDoc2Document->GetDocShell()->GetDoc());
1475 SwEditShell* const pEditShell(pDoc->GetEditShell());
1476 CPPUNIT_ASSERT(pEditShell);
1477 pEditShell->MergeDoc(*pDoc2);
1479 // accept all redlines
1480 while(pEditShell->GetRedlineCount())
1481 pEditShell->AcceptRedline(0);
1483 CPPUNIT_ASSERT_EQUAL(7, getParagraphs());
1484 getParagraph(1, u"Para One: Two Three Four Five"_ustr);
1485 getParagraph(2, u"Para Two: One Three Four Five"_ustr);
1486 getParagraph(3, u"Para Three: One Two Four Five"_ustr);
1487 getParagraph(4, u"Para Four: One Two Three Four Five"_ustr);
1488 getParagraph(5, u"Para Six: One Three Four Five"_ustr);
1489 getParagraph(6, u""_ustr);
1490 getParagraph(7, u""_ustr);
1493 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCreatePortions)
1495 createSwDoc("uno-cycle.odt");
1496 uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
1497 uno::Reference<text::XTextContent> xText(xBookmarksSupplier->getBookmarks()->getByName(u"Mark"_ustr), uno::UNO_QUERY);
1498 uno::Reference<container::XEnumerationAccess> xTextCursor(xText->getAnchor(), uno::UNO_QUERY);
1499 CPPUNIT_ASSERT(xTextCursor.is());
1501 uno::Reference<container::XEnumerationAccess> xParagraph(
1502 xTextCursor->createEnumeration()->nextElement(), uno::UNO_QUERY);
1503 CPPUNIT_ASSERT(xParagraph.is());
1504 // This looped forever in lcl_CreatePortions
1505 xParagraph->createEnumeration();
1508 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testBookmarkUndo)
1510 createSwDoc();
1511 SwDoc* pDoc = getSwDoc();
1512 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1513 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1514 SwPaM aPaM( SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1) );
1516 pMarkAccess->makeMark(aPaM, u"Mark"_ustr, IDocumentMarkAccess::MarkType::BOOKMARK,
1517 ::sw::mark::InsertMode::New);
1518 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1519 rUndoManager.Undo();
1520 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
1521 rUndoManager.Redo();
1522 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1524 auto ppBkmk = pMarkAccess->findMark(u"Mark"_ustr);
1525 CPPUNIT_ASSERT(ppBkmk != pMarkAccess->getAllMarksEnd());
1527 pMarkAccess->renameMark(*ppBkmk, u"Mark_"_ustr);
1528 CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark"_ustr) == pMarkAccess->getAllMarksEnd()));
1529 CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark_"_ustr) != pMarkAccess->getAllMarksEnd());
1530 rUndoManager.Undo();
1531 CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark"_ustr) != pMarkAccess->getAllMarksEnd());
1532 CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark_"_ustr) == pMarkAccess->getAllMarksEnd()));
1533 rUndoManager.Redo();
1534 CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark"_ustr) == pMarkAccess->getAllMarksEnd()));
1535 CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark_"_ustr) != pMarkAccess->getAllMarksEnd());
1537 pMarkAccess->deleteMark(pMarkAccess->findMark(u"Mark_"_ustr), false);
1538 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
1539 rUndoManager.Undo();
1540 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1541 rUndoManager.Redo();
1542 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
1545 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf148389_Left)
1547 createSwDoc();
1548 SwDoc* pDoc = getSwDoc();
1549 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1550 CPPUNIT_ASSERT(pWrtShell);
1551 pWrtShell->Insert(u"foo bar baz"_ustr);
1552 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
1553 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 3, /*bBasicCall=*/false);
1554 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1556 auto pMark = pMarkAccess->makeMark(*pWrtShell->GetCursor(), u"Mark"_ustr,
1557 IDocumentMarkAccess::MarkType::BOOKMARK, ::sw::mark::InsertMode::New);
1558 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1559 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
1560 pWrtShell->DelLeft();
1561 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1562 CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pMark->GetOtherMarkPos().GetContentIndex());
1563 pWrtShell->DelLeft();
1564 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pMark->GetOtherMarkPos().GetContentIndex());
1565 pWrtShell->DelLeft();
1566 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
1567 pWrtShell->DelLeft();
1568 // historically it wasn't deleted if empty, not sure if it should be
1569 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1570 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
1571 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetOtherMarkPos().GetContentIndex());
1572 pWrtShell->Undo();
1573 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1574 // Undo re-creates the mark...
1575 pMark = *pMarkAccess->getAllMarksBegin();
1576 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
1577 // the problem was that the end position was not restored
1578 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
1579 pWrtShell->Undo();
1580 // this undo is no longer grouped, to prevent Redo deleting bookmark
1581 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1582 // Undo re-creates the mark...
1583 pMark = *pMarkAccess->getAllMarksBegin();
1584 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
1585 CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pMark->GetOtherMarkPos().GetContentIndex());
1586 pWrtShell->Redo();
1587 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1588 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
1589 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
1590 pWrtShell->Redo();
1591 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1592 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
1593 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetOtherMarkPos().GetContentIndex());
1594 pWrtShell->Undo();
1595 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1596 // Undo re-creates the mark...
1597 pMark = *pMarkAccess->getAllMarksBegin();
1598 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
1599 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
1600 pWrtShell->Undo();
1601 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1602 // Undo re-creates the mark...
1603 pMark = *pMarkAccess->getAllMarksBegin();
1604 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
1605 CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pMark->GetOtherMarkPos().GetContentIndex());
1608 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf148389_Right)
1610 createSwDoc();
1611 SwDoc* pDoc = getSwDoc();
1612 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1613 CPPUNIT_ASSERT(pWrtShell);
1614 pWrtShell->Insert(u"foo bar baz"_ustr);
1615 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
1616 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 3, /*bBasicCall=*/false);
1617 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1619 auto pMark = pMarkAccess->makeMark(*pWrtShell->GetCursor(), u"Mark"_ustr,
1620 IDocumentMarkAccess::MarkType::BOOKMARK, ::sw::mark::InsertMode::New);
1621 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1622 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
1623 pWrtShell->DelRight();
1624 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1625 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetMarkPos().GetContentIndex());
1626 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pMark->GetOtherMarkPos().GetContentIndex());
1627 pWrtShell->DelRight();
1628 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
1629 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
1630 pWrtShell->DelRight();
1631 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
1632 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetOtherMarkPos().GetContentIndex());
1633 pWrtShell->DelRight();
1634 // historically it wasn't deleted if empty, not sure if it should be
1635 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1636 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
1637 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetOtherMarkPos().GetContentIndex());
1638 pWrtShell->Undo();
1639 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1640 // Undo re-creates the mark...
1641 pMark = *pMarkAccess->getAllMarksBegin();
1642 // the problem was that the start position was not restored
1643 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
1644 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
1645 pWrtShell->Undo();
1646 // this undo is no longer grouped, to prevent Redo deleting bookmark
1647 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1648 // Undo re-creates the mark...
1649 pMark = *pMarkAccess->getAllMarksBegin();
1650 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetMarkPos().GetContentIndex());
1651 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pMark->GetOtherMarkPos().GetContentIndex());
1652 pWrtShell->Undo();
1653 // this undo is no longer grouped, to prevent Redo deleting bookmark
1654 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1655 // Undo re-creates the mark...
1656 pMark = *pMarkAccess->getAllMarksBegin();
1657 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
1658 CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pMark->GetOtherMarkPos().GetContentIndex());
1659 pWrtShell->Redo();
1660 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1661 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetMarkPos().GetContentIndex());
1662 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pMark->GetOtherMarkPos().GetContentIndex());
1663 pWrtShell->Redo();
1664 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1665 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
1666 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
1667 pWrtShell->Redo();
1668 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1669 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
1670 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetOtherMarkPos().GetContentIndex());
1671 pWrtShell->Undo();
1672 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1673 // Undo re-creates the mark...
1674 pMark = *pMarkAccess->getAllMarksBegin();
1675 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
1676 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
1677 pWrtShell->Undo();
1678 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1679 // Undo re-creates the mark...
1680 pMark = *pMarkAccess->getAllMarksBegin();
1681 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetMarkPos().GetContentIndex());
1682 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pMark->GetOtherMarkPos().GetContentIndex());
1683 pWrtShell->Undo();
1684 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1685 // Undo re-creates the mark...
1686 pMark = *pMarkAccess->getAllMarksBegin();
1687 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
1688 CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pMark->GetOtherMarkPos().GetContentIndex());
1691 static void lcl_setWeight(SwWrtShell* pWrtShell, FontWeight aWeight)
1693 SvxWeightItem aWeightItem(aWeight, EE_CHAR_WEIGHT);
1694 SvxScriptSetItem aScriptSetItem(SID_ATTR_CHAR_WEIGHT, pWrtShell->GetAttrPool());
1695 aScriptSetItem.PutItemForScriptType(SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX, aWeightItem);
1696 pWrtShell->SetAttrSet(aScriptSetItem.GetItemSet());
1699 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo85876)
1701 createSwDoc();
1702 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1703 lcl_setWeight(pWrtShell, WEIGHT_BOLD);
1704 pWrtShell->Insert(u"test"_ustr);
1705 lcl_setWeight(pWrtShell, WEIGHT_NORMAL);
1706 pWrtShell->SplitNode();
1707 pWrtShell->SplitNode();
1708 pWrtShell->Up(false);
1709 pWrtShell->Insert(u"test"_ustr);
1710 auto xText = getParagraph(1)->getText();
1711 CPPUNIT_ASSERT(xText.is());
1713 auto xCursor(xText->createTextCursorByRange(getParagraph(1)));
1714 CPPUNIT_ASSERT(xCursor.is());
1715 xCursor->collapseToStart();
1716 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, u"CharWeight"_ustr));
1719 auto xCursor(xText->createTextCursorByRange(getParagraph(2)));
1720 CPPUNIT_ASSERT(xCursor.is());
1721 xCursor->collapseToStart();
1722 // this used to be BOLD too with fdo#85876
1723 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xCursor, u"CharWeight"_ustr));
1727 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCaretPositionMovingUp)
1729 createSwDoc();
1730 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1731 pWrtShell->Insert(u"after"_ustr);
1732 pWrtShell->InsertLineBreak();
1733 pWrtShell->Up(false);
1734 pWrtShell->Insert(u"before"_ustr);
1736 CPPUNIT_ASSERT_EQUAL(OUString(u"beforeAfter" + OUStringChar(CH_TXTATR_NEWLINE)), getParagraph(1)->getString());
1739 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf93441)
1741 createSwDoc();
1742 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1743 pWrtShell->Insert(u"Hello"_ustr);
1744 pWrtShell->InsertLineBreak();
1745 pWrtShell->Insert(u"Hello World"_ustr);
1746 pWrtShell->Up(false);
1747 pWrtShell->Insert(u" World"_ustr);
1749 // Without the fix in place, this test would have failed with
1750 // - Expected: Hello World\nHello World
1751 // - Actual : WorldHello\nHello World
1752 CPPUNIT_ASSERT_EQUAL(OUString(u"Hello World" + OUStringChar(CH_TXTATR_NEWLINE) + u"Hello World"), getParagraph(1)->getString());
1755 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf81226)
1757 createSwDoc();
1758 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1759 pWrtShell->Insert(u"before"_ustr);
1760 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
1761 pWrtShell->Down(false);
1762 pWrtShell->Insert(u"after"_ustr);
1764 // Without the fix in place, this test would have failed with
1765 // - Expected: beforeafter
1766 // - Actual : beafterfore
1767 CPPUNIT_ASSERT_EQUAL(u"beforeafter"_ustr, getParagraph(1)->getString());
1770 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf137532)
1772 createSwDoc();
1773 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1774 pWrtShell->Insert(u"test"_ustr);
1776 //Select the word and change it to bold
1777 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 4, /*bBasicCall=*/false);
1778 lcl_setWeight(pWrtShell, WEIGHT_BOLD);
1780 // Select first character and replace it
1781 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1782 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1783 pWrtShell->Insert(u"x"_ustr);
1785 auto xText = getParagraph(1)->getText();
1786 CPPUNIT_ASSERT(xText.is());
1787 auto xCursor(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
1789 CPPUNIT_ASSERT(xCursor.is());
1790 CPPUNIT_ASSERT_EQUAL(u"xest"_ustr, xCursor->getString());
1791 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, u"CharWeight"_ustr));
1793 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
1795 xCursor.set(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
1796 CPPUNIT_ASSERT(xCursor.is());
1797 CPPUNIT_ASSERT_EQUAL(u"test"_ustr, xCursor->getString());
1799 // Without the fix in place, this test would have failed in
1800 // - Expected: 150
1801 // - Actual : 100
1802 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, u"CharWeight"_ustr));
1804 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
1806 xCursor.set(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
1807 CPPUNIT_ASSERT(xCursor.is());
1808 CPPUNIT_ASSERT_EQUAL(u"test"_ustr, xCursor->getString());
1809 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xCursor, u"CharWeight"_ustr));
1812 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo87448)
1814 createSwDoc("fdo87448.odt");
1816 // Save the first shape to a metafile.
1817 uno::Reference<drawing::XGraphicExportFilter> xGraphicExporter = drawing::GraphicExportFilter::create(comphelper::getProcessComponentContext());
1818 uno::Reference<lang::XComponent> xSourceDoc(getShape(1), uno::UNO_QUERY);
1819 xGraphicExporter->setSourceDocument(xSourceDoc);
1821 SvMemoryStream aStream;
1822 uno::Reference<io::XOutputStream> xOutputStream(new utl::OStreamWrapper(aStream));
1823 uno::Sequence<beans::PropertyValue> aDescriptor( comphelper::InitPropertySequence({
1824 { "OutputStream", uno::Any(xOutputStream) },
1825 { "FilterName", uno::Any(u"SVM"_ustr) }
1826 }));
1827 xGraphicExporter->filter(aDescriptor);
1828 aStream.Seek(STREAM_SEEK_TO_BEGIN);
1830 // Read it back and dump it as an XML file.
1831 Graphic aGraphic;
1832 TypeSerializer aSerializer(aStream);
1833 aSerializer.readGraphic(aGraphic);
1834 const GDIMetaFile& rMetaFile = aGraphic.GetGDIMetaFile();
1835 MetafileXmlDump dumper;
1836 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, rMetaFile);
1838 // The first polyline in the document has a number of points to draw arcs,
1839 // the last one jumps back to the start, so we call "end" the last but one.
1840 sal_Int32 nFirstEnd = getXPath(pXmlDoc, "(//polyline)[1]/point[last()-1]", "x").toInt32();
1841 // The second polyline has a different start point, but the arc it draws
1842 // should end at the ~same position as the first polyline.
1843 sal_Int32 nSecondEnd = getXPath(pXmlDoc, "(//polyline)[2]/point[last()]", "x").toInt32();
1845 // nFirstEnd was 6023 and nSecondEnd was 6648, now they should be much closer, e.g. nFirstEnd = 6550, nSecondEnd = 6548
1846 OString aMsg = "nFirstEnd is " + OString::number(nFirstEnd) + ", nSecondEnd is " + OString::number(nSecondEnd);
1847 // Assert that the difference is less than half point.
1848 CPPUNIT_ASSERT_MESSAGE(aMsg.getStr(), abs(nFirstEnd - nSecondEnd) < 10);
1851 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTextCursorInvalidation)
1853 createSwDoc();
1854 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1855 uno::Reference<beans::XPropertySet> xPageStyle(getStyles(u"PageStyles"_ustr)->getByName(u"Standard"_ustr), uno::UNO_QUERY);
1856 CPPUNIT_ASSERT(xPageStyle.is());
1857 xPageStyle->setPropertyValue(u"HeaderIsOn"_ustr, uno::Any(true));
1858 uno::Reference<text::XText> xHeader(getProperty<uno::Reference<text::XText>>(xPageStyle, u"HeaderText"_ustr));
1859 CPPUNIT_ASSERT(xHeader.is());
1860 // create cursor inside the header text
1861 uno::Reference<text::XTextCursor> xCursor(xHeader->createTextCursor());
1862 // can't go right in empty header
1863 CPPUNIT_ASSERT(!xCursor->goRight(1, false));
1864 // this does not actually delete the header: xPageStyle->setPropertyValue("HeaderIsOn", uno::makeAny(false));
1865 pWrtShell->ChangeHeaderOrFooter(u"Default Page Style", true, false, false);
1866 // must be disposed after deleting header
1867 // cursor ends up in body
1868 // UPDATE: this behaviour has been corrected as a side effect of the fix to tdf#46561:
1869 //CPPUNIT_ASSERT_THROW(xCursor->goRight(1, false), uno::RuntimeException);
1872 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf68183)
1874 // First disable RSID and check if indeed no such attribute is inserted.
1875 createSwDoc();
1876 SwDoc* pDoc = getSwDoc();
1877 SwModule* mod = SwModule::get();
1878 mod->GetModuleConfig()->SetStoreRsid(false);
1879 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1880 pWrtShell->Insert2(u"X"_ustr);
1882 SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
1883 SwPaM aPaM(aIdx);
1884 SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
1885 CPPUNIT_ASSERT_EQUAL(false, pTextNode->GetSwAttrSet().HasItem(RES_PARATR_RSID));
1887 // Then enable storing of RSID and make sure that the attribute is inserted.
1888 mod->GetModuleConfig()->SetStoreRsid(true);
1890 pWrtShell->DelToStartOfLine();
1891 pWrtShell->Insert2(u"X"_ustr);
1893 CPPUNIT_ASSERT_EQUAL(true, pTextNode->GetSwAttrSet().HasItem(RES_PARATR_RSID));
1896 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCp1000115)
1898 createSwDoc("cp1000115.fodt");
1899 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1900 // This was 1: the long paragraph in the B1 cell did flow over to the
1901 // second page, so there was only one paragraph in the second cell of the
1902 // second page.
1903 assertXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell[2]/txt", 2);
1906 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf63214)
1908 //This is a crash test
1909 createSwDoc();
1910 SwDoc* pDoc = getSwDoc();
1911 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1912 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1913 pWrtShell->Insert(u"V"_ustr);
1914 { //limiting the lifetime of SwPaM with a nested scope
1915 //the shell cursor are automatically adjusted when nodes are deleted, but the shell doesn't know about an SwPaM on the stack
1916 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1917 SwPaM aPaM( SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1) );
1918 aPaM.SetMark();
1919 aPaM.Move(fnMoveForward, GoInContent);
1920 //Inserting a crossRefBookmark
1921 pMarkAccess->makeMark(aPaM, u"Bookmark"_ustr,
1922 IDocumentMarkAccess::MarkType::CROSSREF_HEADING_BOOKMARK,
1923 ::sw::mark::InsertMode::New);
1924 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1926 //moving cursor to the end of paragraph
1927 pWrtShell->EndPara();
1928 //inserting paragraph break
1929 pWrtShell->SplitNode();
1930 rUndoManager.Undo();
1931 rUndoManager.Redo();
1934 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf90003)
1936 createSwDoc("tdf90003.odt");
1937 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1938 CPPUNIT_ASSERT(pXmlDoc);
1939 // This was 1: an unexpected fly portion was created, resulting in too
1940 // large x position for the empty paragraph marker.
1941 assertXPath(pXmlDoc, "//SwFixPortion[@type='PortionType::Fly']", 0);
1944 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf51741)
1946 createSwDoc();
1947 SwDoc* pDoc = getSwDoc();
1948 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1949 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1950 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1951 SwPaM aPaM( SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1) );
1952 //Modification 1
1953 pMarkAccess->makeMark(aPaM, u"Mark"_ustr, IDocumentMarkAccess::MarkType::BOOKMARK,
1954 ::sw::mark::InsertMode::New);
1955 CPPUNIT_ASSERT(pWrtShell->IsModified());
1956 pWrtShell->ResetModified();
1957 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1958 //Modification 2
1959 rUndoManager.Undo();
1960 CPPUNIT_ASSERT(pWrtShell->IsModified());
1961 pWrtShell->ResetModified();
1962 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
1963 //Modification 3
1964 rUndoManager.Redo();
1965 CPPUNIT_ASSERT(pWrtShell->IsModified());
1966 pWrtShell->ResetModified();
1967 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1968 auto ppBkmk = pMarkAccess->findMark(u"Mark"_ustr);
1969 CPPUNIT_ASSERT(ppBkmk != pMarkAccess->getAllMarksEnd());
1970 //Modification 4
1971 pMarkAccess->renameMark(*ppBkmk, u"Mark_"_ustr);
1972 CPPUNIT_ASSERT(pWrtShell->IsModified());
1973 pWrtShell->ResetModified();
1974 CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark"_ustr) == pMarkAccess->getAllMarksEnd()));
1975 CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark_"_ustr) != pMarkAccess->getAllMarksEnd());
1976 //Modification 5
1977 rUndoManager.Undo();
1978 CPPUNIT_ASSERT(pWrtShell->IsModified());
1979 pWrtShell->ResetModified();
1980 CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark"_ustr) != pMarkAccess->getAllMarksEnd());
1981 CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark_"_ustr) == pMarkAccess->getAllMarksEnd()));
1982 //Modification 6
1983 rUndoManager.Redo();
1984 CPPUNIT_ASSERT(pWrtShell->IsModified());
1985 pWrtShell->ResetModified();
1986 CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark"_ustr) == pMarkAccess->getAllMarksEnd()));
1987 CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark_"_ustr) != pMarkAccess->getAllMarksEnd());
1988 //Modification 7
1989 pMarkAccess->deleteMark(pMarkAccess->findMark(u"Mark_"_ustr), false);
1990 CPPUNIT_ASSERT(pWrtShell->IsModified());
1991 pWrtShell->ResetModified();
1992 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
1993 //Modification 8
1994 rUndoManager.Undo();
1995 CPPUNIT_ASSERT(pWrtShell->IsModified());
1996 pWrtShell->ResetModified();
1997 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
1998 //Modification 9
1999 rUndoManager.Redo();
2000 CPPUNIT_ASSERT(pWrtShell->IsModified());
2001 pWrtShell->ResetModified();
2002 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
2005 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDefaultsOfOutlineNumbering)
2007 uno::Reference<text::XDefaultNumberingProvider> xDefNum(m_xSFactory->createInstance(u"com.sun.star.text.DefaultNumberingProvider"_ustr), uno::UNO_QUERY);
2008 css::lang::Locale alocale;
2009 alocale.Language = "en";
2010 alocale.Country = "US";
2011 const uno::Sequence<beans::PropertyValues> aPropVal(xDefNum->getDefaultContinuousNumberingLevels(alocale));
2012 CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aPropVal.getLength());
2013 for(const auto& rPropValues : aPropVal)
2015 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), rPropValues.getLength());
2016 for(const auto& rPropVal : rPropValues)
2018 uno::Any aAny = rPropVal.Value;
2019 if(rPropVal.Name == "Prefix" || rPropVal.Name == "Suffix" || rPropVal.Name == "Transliteration")
2020 CPPUNIT_ASSERT_EQUAL(u"string"_ustr, aAny.getValueTypeName());
2021 else if(rPropVal.Name == "NumberingType")
2022 CPPUNIT_ASSERT_EQUAL(u"short"_ustr, aAny.getValueTypeName());
2023 else if(rPropVal.Name == "NatNum")
2024 CPPUNIT_ASSERT_EQUAL(u"short"_ustr, aAny.getValueTypeName());
2025 //It is expected to be long but right now its short !error!
2026 else
2027 CPPUNIT_FAIL("Property Name not matched");
2032 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDeleteTableRedlines)
2034 createSwDoc();
2035 SwDoc* pDoc = getSwDoc();
2036 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2037 SwInsertTableOptions TableOpt(SwInsertTableFlags::DefaultBorder, 0);
2038 const SwTable& rTable = pWrtShell->InsertTable(TableOpt, 1, 3);
2039 uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
2040 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getRows()->getCount());
2041 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getColumns()->getCount());
2042 uno::Sequence<beans::PropertyValue> aDescriptor;
2043 SwUnoCursorHelper::makeTableCellRedline((*const_cast<SwTableBox*>(rTable.GetTableBox(u"A1"_ustr))), u"TableCellInsert", aDescriptor);
2044 SwUnoCursorHelper::makeTableCellRedline((*const_cast<SwTableBox*>(rTable.GetTableBox(u"B1"_ustr))), u"TableCellInsert", aDescriptor);
2045 SwUnoCursorHelper::makeTableCellRedline((*const_cast<SwTableBox*>(rTable.GetTableBox(u"C1"_ustr))), u"TableCellInsert", aDescriptor);
2046 IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess();
2047 SwExtraRedlineTable& rExtras = rIDRA.GetExtraRedlineTable();
2048 rExtras.DeleteAllTableRedlines(*pDoc, rTable, false, RedlineType::Any);
2049 CPPUNIT_ASSERT_EQUAL(o3tl::narrowing<sal_uInt16>(0), rExtras.GetSize());
2052 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testXFlatParagraph)
2054 createSwDoc();
2055 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2056 //Inserting some text in the document
2057 pWrtShell->Insert(u"This is sample text"_ustr);
2058 pWrtShell->SplitNode();
2059 pWrtShell->Insert(u"This is another sample text"_ustr);
2060 pWrtShell->SplitNode();
2061 pWrtShell->Insert(u"This is yet another sample text"_ustr);
2062 //retrieving the XFlatParagraphs
2063 uno::Reference<text::XFlatParagraphIteratorProvider> xFPIP(mxComponent, uno::UNO_QUERY);
2064 uno::Reference<text::XFlatParagraphIterator> xFPIterator(xFPIP->getFlatParagraphIterator(sal_Int32(text::TextMarkupType::SPELLCHECK), true));
2065 uno::Reference<text::XFlatParagraph> xFlatPara(xFPIterator->getFirstPara());
2066 CPPUNIT_ASSERT_EQUAL(u"This is sample text"_ustr, xFlatPara->getText());
2067 //checking modified status
2068 CPPUNIT_ASSERT(!xFlatPara->isModified());
2069 //checking "checked" status, modifying it and asserting the changes
2070 CPPUNIT_ASSERT(!xFlatPara->isChecked(sal_Int32(text::TextMarkupType::SPELLCHECK)));
2071 xFlatPara->setChecked((sal_Int32(text::TextMarkupType::SPELLCHECK)), true);
2072 CPPUNIT_ASSERT(xFlatPara->isChecked(sal_Int32(text::TextMarkupType::SPELLCHECK)));
2073 //getting other XFlatParagraphs and asserting their contents
2074 uno::Reference<text::XFlatParagraph> xFlatPara2(xFPIterator->getParaAfter(xFlatPara));
2075 CPPUNIT_ASSERT_EQUAL(u"This is another sample text"_ustr, xFlatPara2->getText());
2076 uno::Reference<text::XFlatParagraph> xFlatPara3(xFPIterator->getParaAfter(xFlatPara2));
2077 CPPUNIT_ASSERT_EQUAL(u"This is yet another sample text"_ustr, xFlatPara3->getText());
2078 uno::Reference<text::XFlatParagraph> xFlatPara4(xFPIterator->getParaBefore(xFlatPara3));
2079 CPPUNIT_ASSERT_EQUAL(xFlatPara2->getText(), xFlatPara4->getText());
2080 //changing the attributes of last para
2081 uno::Sequence<beans::PropertyValue> aDescriptor( comphelper::InitPropertySequence({
2082 { "CharWeight", uno::Any(float(css::awt::FontWeight::BOLD)) }
2083 }));
2084 xFlatPara3->changeAttributes(sal_Int32(0), sal_Int32(5), aDescriptor);
2085 //checking Language Portions
2086 uno::Sequence<::sal_Int32> aLangPortions(xFlatPara4->getLanguagePortions());
2087 CPPUNIT_ASSERT(!aLangPortions.hasElements());
2088 //examining Language of text
2089 css::lang::Locale alocale = xFlatPara4->getLanguageOfText(sal_Int32(0), sal_Int32(4));
2090 CPPUNIT_ASSERT_EQUAL(u"en"_ustr, alocale.Language);
2091 CPPUNIT_ASSERT_EQUAL(u"US"_ustr, alocale.Country);
2092 //examining Primary Language of text
2093 css::lang::Locale aprimarylocale = xFlatPara4->getPrimaryLanguageOfText(sal_Int32(0), sal_Int32(20));
2094 CPPUNIT_ASSERT_EQUAL(u"en"_ustr, aprimarylocale.Language);
2095 CPPUNIT_ASSERT_EQUAL(u"US"_ustr, aprimarylocale.Country);
2098 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf81995)
2100 uno::Reference<text::XDefaultNumberingProvider> xDefNum(m_xSFactory->createInstance(u"com.sun.star.text.DefaultNumberingProvider"_ustr), uno::UNO_QUERY);
2101 css::lang::Locale alocale;
2102 alocale.Language = "en";
2103 alocale.Country = "US";
2104 const uno::Sequence<uno::Reference<container::XIndexAccess>> aIndexAccess(xDefNum->getDefaultOutlineNumberings(alocale));
2105 CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aIndexAccess.getLength());
2106 for(const auto& rIndexAccess : aIndexAccess)
2108 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), rIndexAccess->getCount());
2109 for(int j=0;j<rIndexAccess->getCount();j++)
2111 uno::Sequence<beans::PropertyValue> aProps;
2112 rIndexAccess->getByIndex(j) >>= aProps;
2113 CPPUNIT_ASSERT_EQUAL(sal_Int32(12), aProps.getLength());
2114 for (const beans::PropertyValue& rProp : aProps)
2116 uno::Any aAny = rProp.Value;
2117 if(rProp.Name == "Prefix" || rProp.Name == "Suffix" || rProp.Name == "BulletChar" || rProp.Name == "BulletFontName" || rProp.Name == "Transliteration")
2118 CPPUNIT_ASSERT_EQUAL(u"string"_ustr, aAny.getValueTypeName());
2119 else if(rProp.Name == "NumberingType" || rProp.Name == "ParentNumbering" || rProp.Name == "Adjust")
2120 CPPUNIT_ASSERT_EQUAL(u"short"_ustr, aAny.getValueTypeName());
2121 else if(rProp.Name == "LeftMargin" || rProp.Name == "SymbolTextDistance" || rProp.Name == "FirstLineOffset" || rProp.Name == "NatNum")
2122 CPPUNIT_ASSERT_EQUAL(u"long"_ustr, aAny.getValueTypeName());
2123 else
2124 CPPUNIT_FAIL("Property Name not matched");
2130 CPPUNIT_PLUGIN_IMPLEMENT();
2132 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */