1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
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>
18 #include <shellio.hxx>
20 #include <drawdoc.hxx>
21 #include <redline.hxx>
22 #include <fmtclds.hxx>
23 #include <dcontact.hxx>
26 #include <swacorr.hxx>
27 #include <swmodule.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>
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>
68 void lcl_selectCharacters(SwPaM
& rPaM
, sal_Int32 first
, sal_Int32 end
)
70 rPaM
.GetPoint()->nContent
.Assign(rPaM
.GetPointContentNode(), first
);
72 rPaM
.GetPoint()->nContent
.Assign(rPaM
.GetPointContentNode(), end
);
76 class SwUiWriterTest
: public SwModelTestBase
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
);
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));
106 void SwUiWriterTest::testRedlineFrame(char const*const 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());
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
)
143 SwDoc
* pDoc
= getSwDoc();
145 sw::UndoManager
& rUndoManager
= pDoc
->GetUndoManager();
147 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
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());
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());
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());
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
)
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
:
299 case SwNodeType::End
:
300 CPPUNIT_ASSERT_MESSAGE("bad overlapping redline", nLevel
!= 0);
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
)
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
>);
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);
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());
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
366 pWrtShell
->SttEndDoc(/*bStt=*/true);
367 CPPUNIT_ASSERT(pWrtShell
->IsCursorInTable());
368 CPPUNIT_ASSERT(!pFly
->GetAnchor().GetContentAnchor()->GetNode().FindTableNode());
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());
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());
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());
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());
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
)
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
);
448 aPaM
.MovePara(GoCurrPara
, fnParaStart
);
449 rIDMA
.makeMark(aPaM
, u
"Mark"_ustr
, IDocumentMarkAccess::MarkType::BOOKMARK
,
450 ::sw::mark::InsertMode::New
);
453 rIDCO
.SplitNode(*aPaM
.GetPoint(), false);
454 rIDCO
.InsertString(aPaM
, u
"baz"_ustr
);
457 rIDCO
.SplitNode(*aPaM
.GetPoint(), false);
458 SwPosition
target(*aPaM
.GetPoint());
459 aPaM
.Move(fnMoveBackward
, GoInContent
);
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
)
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
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
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
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
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
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();
665 CPPUNIT_TEST_FIXTURE(SwUiWriterTest
, testTdf147220
)
668 SwDoc
* pDoc
= getSwDoc();
669 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
671 pWrtShell
->Insert(u
"él"_ustr
);
674 dispatchCommand(mxComponent
, u
".uno:ShowTrackedChanges"_ustr
, {});
675 dispatchCommand(mxComponent
, u
".uno:TrackChanges"_ustr
, {});
676 CPPUNIT_ASSERT(pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
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
)
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
>);
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);
727 dispatchCommand(mxComponent
, u
".uno:ShowTrackedChanges"_ustr
, {});
728 dispatchCommand(mxComponent
, u
".uno:TrackChanges"_ustr
, {});
730 CPPUNIT_ASSERT(pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
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);
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
746 CPPUNIT_ASSERT(pFly
->GetFrame() != nullptr);
749 CPPUNIT_ASSERT(pFly
->GetFrame() != nullptr);
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();
762 // The problem was that SwEditShell::DeleteSel() what this Delete() invokes took the wrong selection...
764 sw::UndoManager
& rUndoManager
= pDoc
->GetUndoManager();
765 // ... so this Undo() call resulted in a crash.
769 CPPUNIT_TEST_FIXTURE(SwUiWriterTest
, testFdo75898
)
771 createSwDoc("fdo75898.odt");
772 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
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
789 SwDoc
* pDoc
= getSwDoc();
791 sw::UndoManager
& rUndoManager
= pDoc
->GetUndoManager();
793 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
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());
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".
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".
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.
889 SwReaderWriter::GetWriter(u
"RTF", OUString(), xWrt
);
890 SvMemoryStream aStream
;
891 SwWriter
aWrt(aStream
, *xClpDoc
);
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
);
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
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
));
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
,
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
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
);
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());
1114 pTextNode
= aIdx
.GetNode().GetTextNode();
1115 CPPUNIT_ASSERT(!pTextNode
->HasHints());
1119 CPPUNIT_TEST_FIXTURE(SwUiWriterTest
, testTdf98512
)
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
)
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());
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
);
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
> );
1237 col
.Init( 2, 0, 10000 );
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
));
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);
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
)
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);
1355 SwHHCWrapper
aWrap( pView
, xContext
, LANGUAGE_CHINESE_TRADITIONAL
, LANGUAGE_CHINESE_SIMPLIFIED
, nullptr,
1356 i18n::TextConversionOption::CHARACTER_BY_CHARACTER
, false,
1357 true, false, false );
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
)
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);
1377 pDoc
->getIDocumentContentOperations().InsertString(aPaM
, NON_CHINESE_CONTENT
);
1380 SwHHCWrapper
aWrap( pView
, xContext
, LANGUAGE_CHINESE_TRADITIONAL
, LANGUAGE_CHINESE_SIMPLIFIED
, nullptr,
1381 i18n::TextConversionOption::CHARACTER_BY_CHARACTER
, false,
1382 true, false, false );
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
)
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);
1402 pDoc
->getIDocumentContentOperations().InsertString(aPaM
, OUString(CHINESE_TRADITIONAL_CONTENT
));
1405 SwHHCWrapper
aWrap( pView
, xContext
, LANGUAGE_CHINESE_TRADITIONAL
, LANGUAGE_CHINESE_SIMPLIFIED
, nullptr,
1406 i18n::TextConversionOption::CHARACTER_BY_CHARACTER
, false,
1407 true, false, false );
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
)
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);
1427 pDoc
->getIDocumentContentOperations().InsertString(aPaM
, OUString(CHINESE_SIMPLIFIED_CONTENT
));
1430 SwHHCWrapper
aWrap( pView
, xContext
, LANGUAGE_CHINESE_SIMPLIFIED
, LANGUAGE_CHINESE_TRADITIONAL
, nullptr,
1431 i18n::TextConversionOption::CHARACTER_BY_CHARACTER
, false,
1432 true, false, false );
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
)
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
)
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());
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());
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());
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());
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());
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());
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
)
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());
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());
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());
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());
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());
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());
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());
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());
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());
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
)
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
)
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
)
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
)
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
)
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
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
) }
1827 xGraphicExporter
->filter(aDescriptor
);
1828 aStream
.Seek(STREAM_SEEK_TO_BEGIN
);
1830 // Read it back and dump it as an XML file.
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
)
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.
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);
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
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
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) );
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
)
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) );
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());
1959 rUndoManager
.Undo();
1960 CPPUNIT_ASSERT(pWrtShell
->IsModified());
1961 pWrtShell
->ResetModified();
1962 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
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());
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());
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()));
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());
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());
1994 rUndoManager
.Undo();
1995 CPPUNIT_ASSERT(pWrtShell
->IsModified());
1996 pWrtShell
->ResetModified();
1997 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
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!
2027 CPPUNIT_FAIL("Property Name not matched");
2032 CPPUNIT_TEST_FIXTURE(SwUiWriterTest
, testDeleteTableRedlines
)
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
)
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
)) }
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());
2124 CPPUNIT_FAIL("Property Name not matched");
2130 CPPUNIT_PLUGIN_IMPLEMENT();
2132 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */