tdf#154285 Check upper bound of arguments in SbRtl_Minute function
[LibreOffice.git] / sw / qa / extras / uiwriter / uiwriter2.cxx
blobb70fea7ce62a37168c9408d6489f535caced54ed
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <swmodeltestbase.hxx>
12 #include <com/sun/star/style/LineSpacing.hpp>
13 #include <com/sun/star/text/TableColumnSeparator.hpp>
14 #include <com/sun/star/text/XTextTable.hpp>
15 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
16 #include <comphelper/propertysequence.hxx>
17 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
18 #include <vcl/scheduler.hxx>
19 #include <vcl/settings.hxx>
20 #include <vcl/filter/PDFiumLibrary.hxx>
21 #include <sfx2/dispatch.hxx>
22 #include <sfx2/viewfrm.hxx>
23 #include <svx/svxids.hrc>
24 #include <view.hxx>
25 #include <ndtxt.hxx>
26 #include <wrtsh.hxx>
27 #include <IDocumentRedlineAccess.hxx>
28 #include <flyfrm.hxx>
29 #include <pagefrm.hxx>
30 #include <fmtanchr.hxx>
31 #include <UndoManager.hxx>
32 #include <sortedobjs.hxx>
33 #include <itabenum.hxx>
34 #include <fmtfsize.hxx>
35 #include <comphelper/scopeguard.hxx>
36 #include <editeng/acorrcfg.hxx>
37 #include <editeng/lrspitem.hxx>
38 #include <swacorr.hxx>
39 #include <redline.hxx>
40 #include <frameformats.hxx>
41 #include <unotxdoc.hxx>
42 #include <IDocumentLayoutAccess.hxx>
43 #include <rootfrm.hxx>
45 /// Second set of tests asserting the behavior of Writer user interface shells.
46 class SwUiWriterTest2 : public SwModelTestBase
48 public:
49 SwUiWriterTest2()
50 : SwModelTestBase(u"/sw/qa/extras/uiwriter/data/"_ustr)
54 protected:
55 AllSettings m_aSavedSettings;
58 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf47471_paraStyleBackground)
60 createSwDoc("tdf47471_paraStyleBackground.odt");
61 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
63 CPPUNIT_ASSERT_EQUAL(u"00Background"_ustr,
64 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
65 CPPUNIT_ASSERT_EQUAL(Color(0xe0c2cd), getProperty<Color>(getParagraph(2), u"FillColor"_ustr));
67 pWrtShell->EndPara(/*bSelect=*/true);
68 pWrtShell->EndPara(/*bSelect=*/true);
69 pWrtShell->EndPara(/*bSelect=*/true);
70 dispatchCommand(mxComponent, u".uno:ResetAttributes"_ustr, {});
72 // the background color should revert to the color for 00Background style
73 CPPUNIT_ASSERT_EQUAL(Color(0xdedce6), getProperty<Color>(getParagraph(2), u"FillColor"_ustr));
74 // the paragraph style should not be reset
75 CPPUNIT_ASSERT_EQUAL(u"00Background"_ustr,
76 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
77 CPPUNIT_ASSERT_EQUAL(u"00Background"_ustr,
78 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
80 // Save it and load it back.
81 saveAndReload(u"writer8"_ustr);
83 CPPUNIT_ASSERT_EQUAL(Color(0xdedce6), getProperty<Color>(getParagraph(2), u"FillColor"_ustr));
84 // on round-trip, the paragraph style name was lost
85 CPPUNIT_ASSERT_EQUAL(u"00Background"_ustr,
86 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
87 CPPUNIT_ASSERT_EQUAL(u"00Background"_ustr,
88 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
91 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdfChangeNumberingListAutoFormat)
93 createSwDoc("tdf117923.docx");
94 SwDoc* pDoc = getSwDoc();
96 // Ensure that all text portions are calculated before testing.
97 SwViewShell* pViewShell = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
98 CPPUNIT_ASSERT(pViewShell);
99 pViewShell->Reformat();
101 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
103 // Check that we actually test the line we need
104 assertXPathContent(pXmlDoc, "/root/page/body/tab/row/cell/txt[3]", u"GHI GHI GHI GHI");
105 assertXPath(pXmlDoc,
106 "/root/page/body/tab/row/cell/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion",
107 "type", u"PortionType::Number");
108 assertXPath(pXmlDoc,
109 "/root/page/body/tab/row/cell/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion",
110 "expand", u"2.");
111 // The numbering height was 960 in DOC format.
112 assertXPath(
113 pXmlDoc,
114 "/root/page/body/tab/row/cell/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont",
115 "height", u"220");
117 // tdf#127606: now it's possible to change formatting of numbering
118 // increase font size (220 -> 260)
119 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
120 dispatchCommand(mxComponent, u".uno:Grow"_ustr, {});
121 pViewShell->Reformat();
122 pXmlDoc = parseLayoutDump();
123 assertXPath(
124 pXmlDoc,
125 "/root/page/body/tab/row/cell/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont",
126 "height", u"260");
128 // save it to DOCX
129 saveAndReload(u"Office Open XML Text"_ustr);
130 pViewShell = getSwDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
131 pViewShell->Reformat();
132 pXmlDoc = parseLayoutDump();
133 // this was 220
134 assertXPath(
135 pXmlDoc,
136 "/root/page/body/tab/row/cell/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont",
137 "height", u"260");
140 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf101534)
142 // Copy the first paragraph of the document.
143 createSwDoc("tdf101534.fodt");
144 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
145 pWrtShell->EndPara(/*bSelect=*/true);
146 dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
148 // Go to the second paragraph, assert that we have margins as direct
149 // formatting.
150 pWrtShell->Down(/*bSelect=*/false);
151 SfxItemSet aSet(pWrtShell->GetAttrPool(),
152 svl::Items<RES_MARGIN_FIRSTLINE, RES_MARGIN_TEXTLEFT>);
153 pWrtShell->GetCurAttr(aSet);
154 CPPUNIT_ASSERT(!aSet.HasItem(RES_MARGIN_FIRSTLINE));
155 CPPUNIT_ASSERT(aSet.HasItem(RES_MARGIN_TEXTLEFT));
156 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aSet.GetItem(RES_MARGIN_TEXTLEFT)->ResolveTextLeft({}));
158 // Make sure that direct formatting is preserved during paste.
159 pWrtShell->EndPara(/*bSelect=*/false);
160 dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
161 aSet.ClearItem();
162 pWrtShell->GetCurAttr(aSet);
163 // This failed, direct formatting was lost.
164 CPPUNIT_ASSERT(!aSet.HasItem(RES_MARGIN_FIRSTLINE));
165 CPPUNIT_ASSERT(aSet.HasItem(RES_MARGIN_TEXTLEFT));
166 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aSet.GetItem(RES_MARGIN_TEXTLEFT)->ResolveTextLeft({}));
169 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testExtendedSelectAllHang)
171 createSwDoc();
172 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
174 pWrtShell->InsertFootnote(u""_ustr);
175 pWrtShell->StartOfSection();
176 SwView* pView = getSwDocShell()->GetView();
177 SfxStringItem aLangString(SID_LANGUAGE_STATUS, u"Default_Spanish (Bolivia)"_ustr);
178 // this looped
179 pView->GetViewFrame().GetDispatcher()->ExecuteList(SID_LANGUAGE_STATUS, SfxCallMode::SYNCHRON,
180 { &aLangString });
183 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineMoveInsertInDelete)
185 createSwDoc();
186 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
188 pWrtShell->Insert(u" foo"_ustr);
189 pWrtShell->SttEndDoc(true);
190 pWrtShell->InsertFootnote(u""_ustr);
191 CPPUNIT_ASSERT(pWrtShell->IsCursorInFootnote());
192 RedlineFlags const mode(pWrtShell->GetRedlineFlags() | RedlineFlags::On);
193 CPPUNIT_ASSERT(mode & (RedlineFlags::ShowDelete | RedlineFlags::ShowInsert));
194 pWrtShell->SetRedlineFlags(mode);
195 // insert redline
196 pWrtShell->Insert(u"bar"_ustr);
197 // first delete redline, logically containing the insert redline
198 // (note: Word apparently allows similar things...)
199 pWrtShell->SttEndDoc(true);
200 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
201 pWrtShell->Delete(); // the footnote
202 // second delete redline, following the first one
203 pWrtShell->EndOfSection(false);
204 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 3, /*bBasicCall=*/false);
205 pWrtShell->Delete(); // "foo"
207 // hiding used to copy the 2nd delete redline "foo", but not delete it
208 pWrtShell->SetRedlineFlags(mode & ~RedlineFlags::ShowDelete); // hide
209 CPPUNIT_ASSERT_EQUAL(u" "_ustr,
210 pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode()->GetText());
211 pWrtShell->SetRedlineFlags(mode); // show again
212 CPPUNIT_ASSERT_EQUAL(u"\u0001 foo"_ustr,
213 pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode()->GetText());
216 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineInHiddenSection)
218 createSwDoc();
219 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
221 pWrtShell->SplitNode();
222 pWrtShell->Insert(u"foo"_ustr);
223 pWrtShell->SplitNode();
224 pWrtShell->Insert(u"bar"_ustr);
225 pWrtShell->SplitNode();
226 pWrtShell->Insert(u"baz"_ustr);
228 RedlineFlags const mode(pWrtShell->GetRedlineFlags() | RedlineFlags::On);
229 CPPUNIT_ASSERT(mode & (RedlineFlags::ShowDelete | RedlineFlags::ShowInsert));
230 pWrtShell->SetRedlineFlags(mode);
232 // delete paragraph "bar"
233 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
234 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 8, /*bBasicCall=*/false);
235 pWrtShell->Delete();
237 pWrtShell->StartOfSection();
238 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
239 pWrtShell->EndOfSection(true);
241 SwSectionData section(SectionType::Content, pWrtShell->GetUniqueSectionName());
242 section.SetHidden(true);
243 SwSection const* pSection = pWrtShell->InsertSection(section, nullptr);
245 SwSectionNode const* pNode = pSection->GetFormat()->GetSectionNode();
247 CPPUNIT_ASSERT(
248 !pNode->GetNodes()[pNode->GetIndex() + 1]->GetTextNode()->getLayoutFrame(nullptr));
249 CPPUNIT_ASSERT(
250 !pNode->GetNodes()[pNode->GetIndex() + 2]->GetTextNode()->getLayoutFrame(nullptr));
251 CPPUNIT_ASSERT(
252 !pNode->GetNodes()[pNode->GetIndex() + 3]->GetTextNode()->getLayoutFrame(nullptr));
253 CPPUNIT_ASSERT(pNode->GetNodes()[pNode->GetIndex() + 4]->IsEndNode());
255 pWrtShell->SetRedlineFlags(mode & ~RedlineFlags::ShowDelete); // hide
257 CPPUNIT_ASSERT(
258 !pNode->GetNodes()[pNode->GetIndex() + 1]->GetTextNode()->getLayoutFrame(nullptr));
259 CPPUNIT_ASSERT(pNode->GetNodes()[pNode->GetIndex() + 2]->IsEndNode());
261 pWrtShell->SetRedlineFlags(mode); // show again
263 CPPUNIT_ASSERT(
264 !pNode->GetNodes()[pNode->GetIndex() + 1]->GetTextNode()->getLayoutFrame(nullptr));
265 // there was a frame created here
266 CPPUNIT_ASSERT(
267 !pNode->GetNodes()[pNode->GetIndex() + 2]->GetTextNode()->getLayoutFrame(nullptr));
268 CPPUNIT_ASSERT(
269 !pNode->GetNodes()[pNode->GetIndex() + 3]->GetTextNode()->getLayoutFrame(nullptr));
270 CPPUNIT_ASSERT(pNode->GetNodes()[pNode->GetIndex() + 4]->IsEndNode());
273 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineSplitContentNode)
275 createSwDoc("try2.fodt");
276 SwDoc* pDoc = getSwDoc();
277 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
279 SwViewOption aViewOptions(*pWrtShell->GetViewOptions());
280 // these are required so that IsBlank() is true
281 aViewOptions.SetBlank(true);
282 aViewOptions.SetViewMetaChars(true);
283 pWrtShell->ApplyViewOptions(aViewOptions);
285 // enable redlining
286 dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
287 // hide
288 dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
290 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
291 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
292 CPPUNIT_ASSERT_MESSAGE(
293 "redlines should be visible",
294 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
296 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
298 calcLayout();
299 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 18, /*bBasicCall=*/false);
300 pWrtShell->SplitNode(true);
301 rUndoManager.Undo();
302 // crashed
303 pWrtShell->SplitNode(true);
304 rUndoManager.Undo();
305 rUndoManager.Redo();
306 rUndoManager.Undo();
307 rUndoManager.Redo();
308 rUndoManager.Undo();
309 pWrtShell->SplitNode(true);
310 rUndoManager.Undo();
313 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137318)
315 createSwDoc();
316 SwDoc* const pDoc = getSwDoc();
317 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
319 pWrtShell->Insert(u"A"_ustr);
321 // enable redlining
322 dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
323 // hide
324 dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
326 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
327 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
328 CPPUNIT_ASSERT_MESSAGE(
329 "redlines should be visible",
330 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
331 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
333 pWrtShell->DelLine();
334 pWrtShell->StartOfSection(false);
335 pWrtShell->SplitNode(true);
336 pWrtShell->SplitNode(true);
338 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
340 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 3);
341 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion", 0);
342 assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion", 0);
343 // not sure why there's an empty text portion here, but it's not a problem
344 assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwParaPortion", 1);
345 assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwParaPortion",
346 "type", u"PortionType::Para");
347 assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwParaPortion",
348 "portion", u"");
350 pWrtShell->Undo();
352 // the problem was that here the "A" showed up again
353 pXmlDoc = parseLayoutDump();
354 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 2);
355 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion", 0);
356 assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion", 1);
357 assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion",
358 "type", u"PortionType::Para");
359 assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion",
360 "portion", u"");
362 pWrtShell->Undo();
364 pXmlDoc = parseLayoutDump();
365 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 1);
366 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion", 1);
367 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
368 "type", u"PortionType::Para");
369 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
370 "portion", u"");
372 pWrtShell->Undo();
374 // now the "A" is no longer deleted
375 pXmlDoc = parseLayoutDump();
376 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 1);
377 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion", 1);
378 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
379 "type", u"PortionType::Para");
380 assertXPath(pXmlDoc,
381 "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[@portion]", 1);
382 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
383 "length", u"1");
385 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
386 "portion", u"A");
389 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf136704)
391 createSwDoc();
392 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
393 SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect());
394 corr.GetSwFlags().bReplaceStyles = true;
395 SvxSwAutoFormatFlags flags(*SwEditShell::GetAutoFormatFlags());
396 comphelper::ScopeGuard const g([=]() { SwEditShell::SetAutoFormatFlags(&flags); });
397 flags.bReplaceStyles = true;
398 SwEditShell::SetAutoFormatFlags(&flags);
400 pWrtShell->Insert(u"test"_ustr);
401 const sal_Unicode cIns = ':';
402 pWrtShell->AutoCorrect(corr, cIns);
404 SwXTextDocument* pTextDoc = getSwTextDoc();
405 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RETURN);
406 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_RETURN);
407 Scheduler::ProcessEventsToIdle();
409 // Without the fix in place, this test would have crashed here
411 CPPUNIT_ASSERT_EQUAL(u"Heading 3"_ustr,
412 getProperty<OUString>(getParagraph(1), u"ParaStyleName"_ustr));
415 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf134250)
417 createSwDoc("tdf134250.fodt");
419 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
420 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
421 uno::UNO_QUERY);
422 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
424 uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
425 uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(),
426 uno::UNO_QUERY);
428 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
430 uno::Reference<text::XTextContent> xTextContent(xSections->getByIndex(0), uno::UNO_QUERY);
431 CPPUNIT_ASSERT_EQUAL(u"foo" SAL_NEWLINE_STRING "bar"_ustr,
432 xTextContent->getAnchor()->getString());
434 // select all with table at start -> 3 times
435 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
436 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
437 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
439 dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
441 dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
443 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
444 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
446 // this would crash in 2 different ways
447 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
449 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
450 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
452 // Without the fix in place, section's content would have been gone after undo
453 CPPUNIT_ASSERT_EQUAL(u"foo" SAL_NEWLINE_STRING "bar"_ustr,
454 xTextContent->getAnchor()->getString());
456 dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
458 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
459 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
461 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
463 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
464 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
465 CPPUNIT_ASSERT_EQUAL(u"foo" SAL_NEWLINE_STRING "bar"_ustr,
466 xTextContent->getAnchor()->getString());
468 dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
470 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
471 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
474 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf134436)
476 createSwDoc("tdf134436.fodt");
478 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
479 CPPUNIT_ASSERT(pWrtShell);
481 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
482 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
483 uno::UNO_QUERY);
484 uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
485 uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(),
486 uno::UNO_QUERY);
488 // select all 3 times, table at the start
489 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
490 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
491 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
493 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
494 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
495 // the stupid SwXTextView::getString doesn't work "for symmetry" so use CursorShell
496 CPPUNIT_ASSERT_EQUAL(u"a\nb\n"_ustr, pWrtShell->GetCursor()->GetText());
498 // first, the section doesn't get deleted
499 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
501 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
502 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
503 CPPUNIT_ASSERT_EQUAL(u""_ustr, pWrtShell->GetCursor()->GetText());
505 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
507 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
508 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
509 CPPUNIT_ASSERT_EQUAL(u"a\nb\n"_ustr, pWrtShell->GetCursor()->GetText());
511 // second, the section does get deleted because point is at the end
512 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
514 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
515 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xSections->getCount());
516 CPPUNIT_ASSERT_EQUAL(u""_ustr, pWrtShell->GetCursor()->GetText());
518 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
520 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
521 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
522 CPPUNIT_ASSERT_EQUAL(u"a\nb\n"_ustr, pWrtShell->GetCursor()->GetText());
524 // the problem was that the section was not deleted on Redo
525 dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
527 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
528 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xSections->getCount());
529 CPPUNIT_ASSERT_EQUAL(u""_ustr, pWrtShell->GetCursor()->GetText());
531 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
533 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
534 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
535 CPPUNIT_ASSERT_EQUAL(u"a\nb\n"_ustr, pWrtShell->GetCursor()->GetText());
537 dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
539 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
540 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xSections->getCount());
541 CPPUNIT_ASSERT_EQUAL(u""_ustr, pWrtShell->GetCursor()->GetText());
544 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf134252)
546 createSwDoc("tdf134252.fodt");
548 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
549 uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
550 xModel->getCurrentController(), uno::UNO_QUERY);
551 uno::Reference<text::XTextRange> xCursor(xTextViewCursorSupplier->getViewCursor());
552 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
553 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
554 uno::UNO_QUERY);
555 uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
556 uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(),
557 uno::UNO_QUERY);
559 // select all with section
560 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
562 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
563 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
564 CPPUNIT_ASSERT_EQUAL(u"bar" SAL_NEWLINE_STRING "baz" SAL_NEWLINE_STRING ""_ustr,
565 xCursor->getString());
567 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
569 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
570 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
571 CPPUNIT_ASSERT_EQUAL(u""_ustr, xCursor->getString());
573 // this would crash
574 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
576 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
577 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
578 CPPUNIT_ASSERT_EQUAL(u"bar" SAL_NEWLINE_STRING "baz" SAL_NEWLINE_STRING ""_ustr,
579 xCursor->getString());
581 dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
583 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
584 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
585 CPPUNIT_ASSERT_EQUAL(u""_ustr, xCursor->getString());
587 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
589 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
590 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
591 CPPUNIT_ASSERT_EQUAL(u"bar" SAL_NEWLINE_STRING "baz" SAL_NEWLINE_STRING ""_ustr,
592 xCursor->getString());
594 dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
596 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
597 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
598 CPPUNIT_ASSERT_EQUAL(u""_ustr, xCursor->getString());
601 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf136452)
603 createSwDoc("tdf136452.fodt");
604 SwDoc* pDoc = getSwDoc();
606 SwNodeOffset const nNodes(pDoc->GetNodes().Count());
608 SwWrtShell* const pWrtShell(getSwDocShell()->GetWrtShell());
610 // first deletion spanning 2 sections
611 pWrtShell->SttEndDoc(false);
612 pWrtShell->SetMark();
613 pWrtShell->Up(true, 2);
614 pWrtShell->Delete();
616 // 2 paragraphs deleted, last section is gone
617 CPPUNIT_ASSERT_EQUAL(nNodes - 4, pDoc->GetNodes().Count());
619 // second deletion spanning 2 sections
620 pWrtShell->SetMark();
621 pWrtShell->Up(true, 3);
622 pWrtShell->Delete();
624 // 3 paragraphs deleted, 2nd section is gone
625 CPPUNIT_ASSERT_EQUAL(nNodes - 9, pDoc->GetNodes().Count());
627 pWrtShell->Undo();
629 // 2 paragraphs deleted, last section is gone
630 CPPUNIT_ASSERT_EQUAL(nNodes - 4, pDoc->GetNodes().Count());
632 // this crashed
633 pWrtShell->Undo();
635 CPPUNIT_ASSERT_EQUAL(nNodes, pDoc->GetNodes().Count());
637 pWrtShell->Redo();
639 // 2 paragraphs deleted, last section is gone
640 CPPUNIT_ASSERT_EQUAL(nNodes - 4, pDoc->GetNodes().Count());
642 pWrtShell->Redo();
644 // 3 paragraphs deleted, 2nd section is gone
645 CPPUNIT_ASSERT_EQUAL(nNodes - 9, pDoc->GetNodes().Count());
648 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf136453)
650 createSwDoc("tdf136453.fodt");
651 SwDoc* pDoc = getSwDoc();
652 SwWrtShell* const pWrtShell(getSwDocShell()->GetWrtShell());
654 SwNodeOffset const nNodes(pDoc->GetNodes().Count());
656 pWrtShell->SttEndDoc(false);
657 pWrtShell->SetMark();
658 pWrtShell->Up(true, 1);
659 pWrtShell->SttPara(true);
660 pWrtShell->Delete();
662 // one paragraph deleted, section is gone
663 CPPUNIT_ASSERT_EQUAL(nNodes - 3, pDoc->GetNodes().Count());
665 pWrtShell->Undo();
667 CPPUNIT_ASSERT_EQUAL(nNodes, pDoc->GetNodes().Count());
669 // check that every node has 1 frame
670 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
671 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 3);
672 assertXPath(pXmlDoc, "/root/page[1]/body/section", 1);
673 assertXPath(pXmlDoc, "/root/page[1]/body/section/txt", 1);
675 pWrtShell->Redo();
677 // one paragraph deleted, section is gone
678 CPPUNIT_ASSERT_EQUAL(nNodes - 3, pDoc->GetNodes().Count());
680 pXmlDoc = parseLayoutDump();
681 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 3);
682 assertXPath(pXmlDoc, "/root/page[1]/body/section", 0);
684 pWrtShell->Undo();
686 CPPUNIT_ASSERT_EQUAL(nNodes, pDoc->GetNodes().Count());
688 pXmlDoc = parseLayoutDump();
689 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 3);
690 assertXPath(pXmlDoc, "/root/page[1]/body/section", 1);
691 assertXPath(pXmlDoc, "/root/page[1]/body/section/txt", 1);
694 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137245)
696 createSwDoc();
697 SwDoc* pDoc = getSwDoc();
698 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
699 SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect());
700 corr.GetSwFlags().bSetBorder = true;
701 // sigh, it's a global... err i mean Singleton design pattern *eyeroll*
702 SvxSwAutoFormatFlags flags(*SwEditShell::GetAutoFormatFlags());
703 comphelper::ScopeGuard const g([=]() { SwEditShell::SetAutoFormatFlags(&flags); });
704 flags.bSetBorder = true;
705 SwEditShell::SetAutoFormatFlags(&flags);
708 SwFormatAnchor anchor(RndStdIds::FLY_AT_PARA);
709 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
710 SfxItemSet flySet(pDoc->GetAttrPool(),
711 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
712 flySet.Put(anchor);
713 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
714 flySet.Put(size); // set a size, else we get 1 char per line...
715 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
716 CPPUNIT_ASSERT(pFly != nullptr);
719 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
720 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
721 SfxItemSet flySet(pDoc->GetAttrPool(),
722 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
723 flySet.Put(anchor);
724 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
725 flySet.Put(size); // set a size, else we get 1 char per line...
726 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
727 CPPUNIT_ASSERT(pFly != nullptr);
729 // move cursor back to body
730 pWrtShell->SttEndDoc(false);
731 // keep first paragraph empty so that its flys may be deleted too
732 //pWrtShell->Insert("abc");
733 pWrtShell->SplitNode(false);
736 SwFormatAnchor anchor(RndStdIds::FLY_AT_PARA);
737 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
738 SfxItemSet flySet(pDoc->GetAttrPool(),
739 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
740 flySet.Put(anchor);
741 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
742 flySet.Put(size); // set a size, else we get 1 char per line...
743 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
744 CPPUNIT_ASSERT(pFly != nullptr);
747 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
748 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
749 SfxItemSet flySet(pDoc->GetAttrPool(),
750 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
751 flySet.Put(anchor);
752 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
753 flySet.Put(size); // set a size, else we get 1 char per line...
754 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
755 CPPUNIT_ASSERT(pFly != nullptr);
758 const auto& rFormats = *pDoc->GetSpzFrameFormats();
759 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rFormats.size());
761 // move cursor back to body
762 pWrtShell->SttEndDoc(false);
763 pWrtShell->Insert(u"---"_ustr);
764 pWrtShell->SplitNode(true);
766 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rFormats.size());
768 // check that the AutoFormat did something
769 pWrtShell->SttEndDoc(true);
770 SfxItemSet set{ pDoc->GetAttrPool(), svl::Items<RES_BOX, RES_BOX> };
771 pWrtShell->GetCurParAttr(set);
772 CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, set.GetItemState(RES_BOX, false));
775 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf132236)
777 createSwDoc("tdf132236.odt");
778 SwDoc* pDoc = getSwDoc();
780 // select everything and delete
781 SwWrtShell* const pWrtShell(getSwDocShell()->GetWrtShell());
782 pWrtShell->Down(true);
783 pWrtShell->Down(true);
784 pWrtShell->Down(true);
785 pWrtShell->Delete();
786 sw::UndoManager& rUndoManager(pDoc->GetUndoManager());
787 rUndoManager.Undo();
789 // check that the text frames exist inside their sections
790 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
791 assertXPath(pXmlDoc, "/root/page[1]/body/section[1]/txt", 1);
792 assertXPath(pXmlDoc, "/root/page[1]/body/section[2]/txt", 2);
793 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 1);
796 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf131912)
798 createSwDoc();
799 SwDoc* const pDoc = getSwDoc();
800 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
802 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
804 sw::UnoCursorPointer pCursor(
805 pDoc->CreateUnoCursor(SwPosition(pDoc->GetNodes().GetEndOfContent(), SwNodeOffset(-1))));
807 pDoc->getIDocumentContentOperations().InsertString(*pCursor, u"foo"_ustr);
810 SfxItemSet flySet(pDoc->GetAttrPool(),
811 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
812 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
813 pWrtShell->StartOfSection(false);
814 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
815 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
816 flySet.Put(anchor);
817 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
818 flySet.Put(size); // set a size, else we get 1 char per line...
819 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
820 CPPUNIT_ASSERT(pFly != nullptr);
822 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
824 pCursor->SetMark();
825 pCursor->GetMark()->nContent.Assign(pCursor->GetPointContentNode(), 0);
826 pCursor->GetPoint()->nContent.Assign(pCursor->GetPointContentNode(), 3);
828 // replace with more text
829 pDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, u"blahblah"_ustr, false);
831 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
832 CPPUNIT_ASSERT_EQUAL(u"blahblah"_ustr, pCursor->GetPointNode().GetTextNode()->GetText());
834 rUndoManager.Undo();
836 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
837 CPPUNIT_ASSERT_EQUAL(u"foo"_ustr, pCursor->GetPointNode().GetTextNode()->GetText());
839 rUndoManager.Redo();
841 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
842 CPPUNIT_ASSERT_EQUAL(u"blahblah"_ustr, pCursor->GetPointNode().GetTextNode()->GetText());
844 rUndoManager.Undo();
846 pCursor->GetMark()->nContent.Assign(pCursor->GetPointContentNode(), 0);
847 pCursor->GetPoint()->nContent.Assign(pCursor->GetPointContentNode(), 3);
849 // replace with less text
850 pDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, u"x"_ustr, false);
852 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
853 CPPUNIT_ASSERT_EQUAL(u"x"_ustr, pCursor->GetPointNode().GetTextNode()->GetText());
855 rUndoManager.Undo();
857 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
858 CPPUNIT_ASSERT_EQUAL(u"foo"_ustr, pCursor->GetPointNode().GetTextNode()->GetText());
860 rUndoManager.Redo();
862 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
863 CPPUNIT_ASSERT_EQUAL(u"x"_ustr, pCursor->GetPointNode().GetTextNode()->GetText());
865 rUndoManager.Undo();
867 pCursor->GetMark()->nContent.Assign(pCursor->GetPointContentNode(), 0);
868 pCursor->GetPoint()->nContent.Assign(pCursor->GetPointContentNode(), 3);
870 // regex replace with paragraph breaks
871 pDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, u"xyz\\n\\nquux\\n"_ustr, true);
873 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
874 pWrtShell->StartOfSection(false);
875 CPPUNIT_ASSERT_EQUAL(u"xyz"_ustr,
876 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
877 pWrtShell->EndOfSection(true);
878 CPPUNIT_ASSERT_EQUAL(u"xyz\n\nquux\n"_ustr, pWrtShell->GetCursor()->GetText());
880 rUndoManager.Undo();
882 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
883 CPPUNIT_ASSERT_EQUAL(u"foo"_ustr, pCursor->GetPointNode().GetTextNode()->GetText());
884 pWrtShell->StartOfSection(false);
885 pWrtShell->EndOfSection(true);
886 CPPUNIT_ASSERT_EQUAL(u"foo"_ustr, pWrtShell->GetCursor()->GetText());
888 rUndoManager.Redo();
890 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
891 pWrtShell->StartOfSection(false);
892 CPPUNIT_ASSERT_EQUAL(u"xyz"_ustr,
893 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
894 pWrtShell->EndOfSection(true);
895 CPPUNIT_ASSERT_EQUAL(u"xyz\n\nquux\n"_ustr, pWrtShell->GetCursor()->GetText());
897 // regex replace with paragraph join
898 pWrtShell->StartOfSection(false);
899 pWrtShell->Down(true);
900 pDoc->getIDocumentContentOperations().ReplaceRange(*pWrtShell->GetCursor(), u"bar"_ustr, true);
902 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
903 pWrtShell->StartOfSection(false);
904 CPPUNIT_ASSERT_EQUAL(u"bar"_ustr,
905 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
906 pWrtShell->EndOfSection(true);
907 CPPUNIT_ASSERT_EQUAL(u"bar\nquux\n"_ustr, pWrtShell->GetCursor()->GetText());
909 rUndoManager.Undo();
911 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
912 pWrtShell->StartOfSection(false);
913 CPPUNIT_ASSERT_EQUAL(u"xyz"_ustr,
914 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
915 pWrtShell->EndOfSection(true);
916 CPPUNIT_ASSERT_EQUAL(u"xyz\n\nquux\n"_ustr, pWrtShell->GetCursor()->GetText());
918 rUndoManager.Redo();
920 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
921 pWrtShell->StartOfSection(false);
922 CPPUNIT_ASSERT_EQUAL(u"bar"_ustr,
923 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
924 pWrtShell->EndOfSection(true);
925 CPPUNIT_ASSERT_EQUAL(u"bar\nquux\n"_ustr, pWrtShell->GetCursor()->GetText());
927 rUndoManager.Undo();
929 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
930 pWrtShell->StartOfSection(false);
931 CPPUNIT_ASSERT_EQUAL(u"xyz"_ustr,
932 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
933 pWrtShell->EndOfSection(true);
934 CPPUNIT_ASSERT_EQUAL(u"xyz\n\nquux\n"_ustr, pWrtShell->GetCursor()->GetText());
936 rUndoManager.Undo();
938 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
939 CPPUNIT_ASSERT_EQUAL(u"foo"_ustr, pCursor->GetPointNode().GetTextNode()->GetText());
940 pWrtShell->StartOfSection(false);
941 pWrtShell->EndOfSection(true);
942 CPPUNIT_ASSERT_EQUAL(u"foo"_ustr, pWrtShell->GetCursor()->GetText());
945 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf140007)
947 createSwDoc();
948 SwDoc* const pDoc = getSwDoc();
949 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
951 pWrtShell->Insert(u"foo"_ustr);
952 pWrtShell->SplitNode();
953 pWrtShell->Insert(u"bar"_ustr);
954 pWrtShell->SplitNode();
955 pWrtShell->Insert(u"baz"_ustr);
956 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(13), pDoc->GetNodes().Count());
957 CPPUNIT_ASSERT_EQUAL(u"foo"_ustr, pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
958 CPPUNIT_ASSERT_EQUAL(u"bar"_ustr, pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
959 CPPUNIT_ASSERT_EQUAL(u"baz"_ustr, pDoc->GetNodes()[SwNodeOffset(11)]->GetTextNode()->GetText());
961 pWrtShell->SttEndDoc(true);
962 pWrtShell->EndPara(false);
963 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
964 pWrtShell->Replace(u" "_ustr, true);
965 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(12), pDoc->GetNodes().Count());
966 CPPUNIT_ASSERT_EQUAL(u"foo bar"_ustr,
967 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
968 CPPUNIT_ASSERT_EQUAL(u"baz"_ustr, pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
970 pWrtShell->SttEndDoc(true);
971 pWrtShell->EndPara(false);
972 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
973 pWrtShell->Replace(u" "_ustr, true);
974 CPPUNIT_ASSERT_EQUAL(u"foo bar baz"_ustr,
975 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
976 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(11), pDoc->GetNodes().Count());
978 pWrtShell->Undo();
980 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(12), pDoc->GetNodes().Count());
981 CPPUNIT_ASSERT_EQUAL(u"foo bar"_ustr,
982 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
983 CPPUNIT_ASSERT_EQUAL(u"baz"_ustr, pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
985 pWrtShell->Undo();
987 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(13), pDoc->GetNodes().Count());
988 CPPUNIT_ASSERT_EQUAL(u"foo"_ustr, pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
989 CPPUNIT_ASSERT_EQUAL(u"bar"_ustr, pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
990 CPPUNIT_ASSERT_EQUAL(u"baz"_ustr, pDoc->GetNodes()[SwNodeOffset(11)]->GetTextNode()->GetText());
992 pWrtShell->Redo();
994 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(12), pDoc->GetNodes().Count());
995 CPPUNIT_ASSERT_EQUAL(u"foo bar"_ustr,
996 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
997 CPPUNIT_ASSERT_EQUAL(u"baz"_ustr, pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
999 pWrtShell->Redo();
1001 CPPUNIT_ASSERT_EQUAL(u"foo bar baz"_ustr,
1002 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
1003 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(11), pDoc->GetNodes().Count());
1005 pWrtShell->Undo();
1007 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(12), pDoc->GetNodes().Count());
1008 CPPUNIT_ASSERT_EQUAL(u"foo bar"_ustr,
1009 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
1010 CPPUNIT_ASSERT_EQUAL(u"baz"_ustr, pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
1012 pWrtShell->Undo();
1014 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(13), pDoc->GetNodes().Count());
1015 CPPUNIT_ASSERT_EQUAL(u"foo"_ustr, pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
1016 CPPUNIT_ASSERT_EQUAL(u"bar"_ustr, pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
1017 CPPUNIT_ASSERT_EQUAL(u"baz"_ustr, pDoc->GetNodes()[SwNodeOffset(11)]->GetTextNode()->GetText());
1020 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf139982)
1022 createSwDoc();
1023 SwDoc* const pDoc = getSwDoc();
1024 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
1026 // turn on redlining and show changes
1027 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1028 | RedlineFlags::ShowInsert);
1029 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1030 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1031 CPPUNIT_ASSERT_MESSAGE(
1032 "redlines should be visible",
1033 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1035 pWrtShell->Insert(u"helloo"_ustr);
1037 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1039 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
1040 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
1041 SfxItemSet flySet(pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>);
1042 flySet.Put(anchor);
1043 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
1044 CPPUNIT_ASSERT(pFly != nullptr);
1047 pWrtShell->SttEndDoc(true);
1048 pWrtShell->EndPara(/*bSelect=*/true);
1050 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1052 pWrtShell->Replace(u"hello"_ustr, true);
1054 // the problem was that a redline delete with the same author as redline
1055 // insert has its text deleted immediately, including anchored flys.
1056 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1058 pWrtShell->Undo();
1060 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1062 pWrtShell->Redo();
1064 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1066 pWrtShell->Undo();
1068 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1071 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf135976)
1073 createSwDoc();
1074 SwDoc* const pDoc = getSwDoc();
1075 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
1077 pWrtShell->Insert(u"foobar"_ustr);
1079 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
1080 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
1081 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
1082 SfxItemSet flySet(pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>);
1083 flySet.Put(anchor);
1084 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
1085 CPPUNIT_ASSERT(pFly != nullptr);
1087 // turn on redlining and show changes
1088 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1089 | RedlineFlags::ShowInsert);
1090 dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
1091 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1092 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1093 CPPUNIT_ASSERT_MESSAGE(
1094 "redlines should be visible",
1095 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1096 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
1098 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1099 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1100 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pFly->GetAnchor().GetAnchorContentOffset());
1102 pWrtShell->UnSelectFrame();
1103 pWrtShell->SttEndDoc(/*bStart=*/false);
1104 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1106 pWrtShell->DelLeft();
1107 pWrtShell->DelLeft();
1109 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1110 // the problem was that the fly was deleted from the layout
1111 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1112 // check that the anchor was moved outside the redline
1113 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pFly->GetAnchor().GetAnchorContentOffset());
1115 pWrtShell->Undo(2);
1117 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1118 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1119 // check that the anchor was restored
1120 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pFly->GetAnchor().GetAnchorContentOffset());
1122 pWrtShell->Redo(2);
1124 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1125 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1126 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pFly->GetAnchor().GetAnchorContentOffset());
1128 pWrtShell->Undo(2);
1130 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1131 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1132 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pFly->GetAnchor().GetAnchorContentOffset());
1134 // now again in the other direction:
1136 pWrtShell->SttEndDoc(/*bStart=*/false);
1137 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 3, /*bBasicCall=*/false);
1139 pWrtShell->DelRight();
1140 pWrtShell->DelRight();
1142 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1143 // the problem was that the fly was deleted from the layout
1144 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1145 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pFly->GetAnchor().GetAnchorContentOffset());
1147 pWrtShell->Undo(2);
1149 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1150 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1151 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pFly->GetAnchor().GetAnchorContentOffset());
1153 pWrtShell->Redo(2);
1155 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1156 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1157 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pFly->GetAnchor().GetAnchorContentOffset());
1159 pWrtShell->Undo(2);
1161 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1162 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1163 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pFly->GetAnchor().GetAnchorContentOffset());
1166 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf39721)
1168 // FIXME: disabled on Windows because of a not reproducible problem (not related to the patch)
1169 #if !defined(_WIN32)
1170 // check move down with redlining
1171 createSwDoc("tdf39721.fodt");
1172 SwDoc* pDoc = getSwDoc();
1174 //turn on red-lining and show changes
1175 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1176 | RedlineFlags::ShowInsert);
1177 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1178 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1179 CPPUNIT_ASSERT_MESSAGE(
1180 "redlines should be visible",
1181 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1183 // store original text of the document for checking Undo
1184 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
1185 OUString sOrigText(xTextDocument->getText()->getString());
1187 // first paragraph is "Lorem ipsum" with deleted "m ips"
1188 CPPUNIT_ASSERT_EQUAL(u"Lorem ipsum"_ustr, getParagraph(1)->getString());
1190 // move down first paragraph with change tracking
1191 dispatchCommand(mxComponent, u".uno:MoveDown"_ustr, {});
1193 // deletion isn't rejected
1194 CPPUNIT_ASSERT_EQUAL(u"Loremm"_ustr, getParagraph(3)->getString());
1196 // Undo and repeat it with the second paragraph
1197 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
1199 CPPUNIT_ASSERT_EQUAL(sOrigText, xTextDocument->getText()->getString());
1201 // second paragraph is "dolor sit" with deleted "lor "
1202 CPPUNIT_ASSERT_EQUAL(u"dolor sit"_ustr, getParagraph(2)->getString());
1204 // move down second paragraph with change tracking
1205 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1207 pWrtShell->Up(/*bSelect=*/false);
1208 pWrtShell->Down(/*bSelect=*/false);
1210 dispatchCommand(mxComponent, u".uno:MoveDown"_ustr, {});
1212 // This was "dolor sit" (rejecting tracked deletion)
1213 CPPUNIT_ASSERT_EQUAL(u"dolsit"_ustr, getParagraph(4)->getString());
1215 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
1217 CPPUNIT_ASSERT_EQUAL(sOrigText, xTextDocument->getText()->getString());
1218 #endif
1221 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf145066_bad_paragraph_deletion)
1223 // check move down with redlining: jumping over a deleted paragraph
1224 // resulted bad deletion of the not deleted adjacent paragraph in Show Changes mode
1225 createSwDoc("tdf39721.fodt");
1226 SwDoc* pDoc = getSwDoc();
1228 //turn on red-lining and show changes
1229 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1230 | RedlineFlags::ShowInsert);
1231 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1232 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1233 CPPUNIT_ASSERT_MESSAGE(
1234 "redlines should be visible",
1235 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1237 // Three paragraphs (list items)
1238 CPPUNIT_ASSERT_EQUAL(3, getParagraphs());
1240 // move down once and move up two times second paragraph with change tracking
1241 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1242 pWrtShell->Down(/*bSelect=*/false);
1243 dispatchCommand(mxComponent, u".uno:MoveDown"_ustr, {});
1244 dispatchCommand(mxComponent, u".uno:MoveUp"_ustr, {});
1245 dispatchCommand(mxComponent, u".uno:MoveUp"_ustr, {});
1247 // accept all changes
1248 dispatchCommand(mxComponent, u".uno:AcceptAllTrackedChanges"_ustr, {});
1250 // This was 2 (bad deletion of the first paragraph)
1251 // TODO fix unnecessary insertion of a new list item at the end of the document
1252 CPPUNIT_ASSERT(getParagraphs() >= 3);
1254 // This was "Loremdolsit\namet.\n" (bad deletion of "m\n" at the end of item 1)
1255 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
1256 CPPUNIT_ASSERT_EQUAL(u"Loremm" SAL_NEWLINE_STRING "dolsit" SAL_NEWLINE_STRING
1257 "amet." SAL_NEWLINE_STRING ""_ustr,
1258 xTextDocument->getText()->getString());
1261 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf145311_move_over_empty_paragraphs)
1263 // check move up/down with redlining: jumping over an empty paragraph
1264 // resulted bad insertion of the empty paragraph in Show Changes mode
1265 createSwDoc("tdf145311.fodt");
1266 SwDoc* pDoc = getSwDoc();
1268 //turn on red-lining and show changes
1269 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1270 | RedlineFlags::ShowInsert);
1271 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1272 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1273 CPPUNIT_ASSERT_MESSAGE(
1274 "redlines should be visible",
1275 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1277 // 8 paragraphs (list items)
1278 CPPUNIT_ASSERT_EQUAL(8, getParagraphs());
1280 // move down the first item over the empty paragraph
1281 for (int i = 0; i < 4; ++i)
1282 dispatchCommand(mxComponent, u".uno:MoveDown"_ustr, {});
1284 SwEditShell* const pEditShell(pDoc->GetEditShell());
1285 CPPUNIT_ASSERT(pEditShell);
1286 // This was 3 (bad conversion of the empty item to a tracked insertion)
1287 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount());
1289 // check move up
1291 for (int i = 0; i < 3; ++i)
1292 dispatchCommand(mxComponent, u".uno:MoveUp"_ustr, {});
1294 // This was 3 (bad conversion of the empty item to a tracked insertion)
1295 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount());
1298 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf54819)
1300 createSwDoc("tdf54819.fodt");
1301 SwDoc* pDoc = getSwDoc();
1303 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
1304 getProperty<OUString>(getParagraph(1), u"ParaStyleName"_ustr));
1305 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1306 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1308 //turn on red-lining and hide changes
1309 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On);
1310 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1311 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1312 CPPUNIT_ASSERT_MESSAGE("redlines shouldn't be visible",
1313 !IDocumentRedlineAccess::IsShowChanges(
1314 pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1316 // remove first paragraph with paragraph break
1317 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1318 pWrtShell->EndPara(/*bSelect=*/true);
1319 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1320 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
1322 // remaining paragraph keeps its original style
1323 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1324 getProperty<OUString>(getParagraph(1), u"ParaStyleName"_ustr));
1327 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf54819_keep_numbering_with_Undo)
1329 createSwDoc("tdf54819b.odt");
1330 SwDoc* pDoc = getSwDoc();
1332 // heading
1333 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
1334 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1335 CPPUNIT_ASSERT_EQUAL(u"Outline"_ustr,
1336 getProperty<OUString>(getParagraph(2), u"NumberingStyleName"_ustr));
1338 // next paragraph: bulleted list item
1340 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1341 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
1342 OUString sNumName = getProperty<OUString>(getParagraph(3), u"NumberingStyleName"_ustr);
1343 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1344 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1346 //turn on red-lining and show changes
1347 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1348 | RedlineFlags::ShowInsert);
1349 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On);
1350 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1351 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1352 CPPUNIT_ASSERT_MESSAGE("redlines shouldn't be visible",
1353 !IDocumentRedlineAccess::IsShowChanges(
1354 pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1356 // remove heading with paragraph break
1357 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1359 pWrtShell->Down(/*bSelect=*/false);
1360 pWrtShell->Down(/*bSelect=*/false);
1361 pWrtShell->Down(/*bSelect=*/false);
1362 pWrtShell->Down(/*bSelect=*/false);
1363 pWrtShell->Down(/*bSelect=*/false);
1364 pWrtShell->EndPara(/*bSelect=*/true);
1365 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1366 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
1368 // solved problem: changing paragraph style after deletion
1369 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1370 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1372 sNumName = getProperty<OUString>(getParagraph(2), u"NumberingStyleName"_ustr);
1373 // solved problem: lost numbering
1374 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1375 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1377 // accept deletion, remaining (now second) paragraph: still bulleted list item
1378 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
1379 rIDRA.AcceptAllRedline(true);
1381 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1382 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1383 sNumName = getProperty<OUString>(getParagraph(2), u"NumberingStyleName"_ustr);
1384 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1385 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1387 // solved problem: Undo with the workaround
1388 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1389 rUndoManager.Undo();
1390 rUndoManager.Undo();
1392 // heading, manual test is correct
1393 // TODO: it works well, but the test fails...
1394 // SwWrtShell* const pWrtShell2 = getSwDocShell()->GetWrtShell();
1395 // CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
1396 // getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1397 // CPPUNIT_ASSERT_EQUAL(OUString("Outline"),
1398 // getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
1400 // next paragraph: bulleted list item
1402 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1403 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
1404 sNumName = getProperty<OUString>(getParagraph(3), u"NumberingStyleName"_ustr);
1405 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1406 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1409 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119571_keep_numbering_with_Undo)
1411 // as the previous test, but with partial paragraph deletion:
1412 // all deleted paragraphs get the formatting of the first (the partially deleted) one
1413 createSwDoc("tdf54819b.odt");
1414 SwDoc* pDoc = getSwDoc();
1416 // heading
1417 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
1418 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1419 CPPUNIT_ASSERT_EQUAL(u"Outline"_ustr,
1420 getProperty<OUString>(getParagraph(2), u"NumberingStyleName"_ustr));
1422 // next paragraph: bulleted list item
1424 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1425 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
1426 OUString sNumName = getProperty<OUString>(getParagraph(3), u"NumberingStyleName"_ustr);
1427 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1428 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1430 // third paragraph: normal text without numbering
1432 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1433 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
1434 sNumName = getProperty<OUString>(getParagraph(4), u"NumberingStyleName"_ustr);
1435 CPPUNIT_ASSERT_MESSAGE("Bad numbering", sNumName.isEmpty());
1437 //turn on red-lining and show changes
1438 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1439 | RedlineFlags::ShowInsert);
1440 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On);
1441 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1442 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1443 CPPUNIT_ASSERT_MESSAGE("redlines shouldn't be visible",
1444 !IDocumentRedlineAccess::IsShowChanges(
1445 pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1447 // remove only end part of the heading and the next numbered paragraph with paragraph break
1448 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1450 pWrtShell->Down(/*bSelect=*/false);
1451 pWrtShell->Down(/*bSelect=*/false);
1452 pWrtShell->Down(/*bSelect=*/false);
1453 pWrtShell->Down(/*bSelect=*/false);
1454 pWrtShell->Down(/*bSelect=*/false);
1455 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 6, /*bBasicCall=*/false);
1456 pWrtShell->EndPara(/*bSelect=*/true);
1457 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 2, /*bBasicCall=*/false);
1458 pWrtShell->EndPara(/*bSelect=*/true);
1459 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1460 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
1462 // solved problem: changing paragraph style after deletion
1463 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
1464 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1466 // solved problem: apply numbering
1467 CPPUNIT_ASSERT_EQUAL(u"Outline"_ustr,
1468 getProperty<OUString>(getParagraph(2), u"NumberingStyleName"_ustr));
1470 // accept deletion
1471 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
1472 rIDRA.AcceptAllRedline(true);
1474 // Joined paragraph 2 and paragraph 4: Fusce...nunc.
1475 CPPUNIT_ASSERT(getParagraph(2)->getString().startsWith("Fusce"));
1476 CPPUNIT_ASSERT(getParagraph(2)->getString().endsWith("nunc."));
1477 // Remaining (now second) paragraph: it is still heading
1478 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
1479 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1480 CPPUNIT_ASSERT_EQUAL(u"Outline"_ustr,
1481 getProperty<OUString>(getParagraph(2), u"NumberingStyleName"_ustr));
1483 // solved problem: Undo with the workaround
1484 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1485 rUndoManager.Undo();
1486 rUndoManager.Undo();
1488 // heading
1490 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
1491 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1492 CPPUNIT_ASSERT_EQUAL(u"Outline"_ustr,
1493 getProperty<OUString>(getParagraph(2), u"NumberingStyleName"_ustr));
1495 // next paragraph: bulleted list item
1497 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1498 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
1499 sNumName = getProperty<OUString>(getParagraph(3), u"NumberingStyleName"_ustr);
1500 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1501 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1503 // third paragraph: normal text without numbering
1505 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1506 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
1507 sNumName = getProperty<OUString>(getParagraph(4), u"NumberingStyleName"_ustr);
1508 CPPUNIT_ASSERT_MESSAGE("Bad numbering", sNumName.isEmpty());
1511 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119571_keep_numbering_with_Reject)
1513 // as the previous test, but with partial paragraph deletion:
1514 // all deleted paragraphs get the formatting of the first (the partially deleted) one
1515 createSwDoc("tdf54819b.odt");
1516 SwDoc* pDoc = getSwDoc();
1518 // heading
1519 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
1520 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1521 CPPUNIT_ASSERT_EQUAL(u"Outline"_ustr,
1522 getProperty<OUString>(getParagraph(2), u"NumberingStyleName"_ustr));
1524 // next paragraph: bulleted list item
1526 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1527 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
1528 OUString sNumName = getProperty<OUString>(getParagraph(3), u"NumberingStyleName"_ustr);
1529 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1530 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1532 // third paragraph: normal text without numbering
1534 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1535 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
1536 sNumName = getProperty<OUString>(getParagraph(4), u"NumberingStyleName"_ustr);
1537 CPPUNIT_ASSERT_MESSAGE("Bad numbering", sNumName.isEmpty());
1539 //turn on red-lining and show changes
1540 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1541 | RedlineFlags::ShowInsert);
1542 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On);
1543 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1544 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1545 CPPUNIT_ASSERT_MESSAGE("redlines shouldn't be visible",
1546 !IDocumentRedlineAccess::IsShowChanges(
1547 pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1549 // remove only end part of the heading and the next numbered paragraph with paragraph break
1550 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1552 pWrtShell->Down(/*bSelect=*/false);
1553 pWrtShell->Down(/*bSelect=*/false);
1554 pWrtShell->Down(/*bSelect=*/false);
1555 pWrtShell->Down(/*bSelect=*/false);
1556 pWrtShell->Down(/*bSelect=*/false);
1557 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 6, /*bBasicCall=*/false);
1558 pWrtShell->EndPara(/*bSelect=*/true);
1559 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 2, /*bBasicCall=*/false);
1560 pWrtShell->EndPara(/*bSelect=*/true);
1561 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1562 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
1564 // solved problem: changing paragraph style after deletion
1565 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
1566 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1568 // solved problem: apply numbering
1569 CPPUNIT_ASSERT_EQUAL(u"Outline"_ustr,
1570 getProperty<OUString>(getParagraph(2), u"NumberingStyleName"_ustr));
1572 // reject deletion
1573 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
1574 rIDRA.AcceptAllRedline(false);
1576 // heading
1578 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
1579 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1580 CPPUNIT_ASSERT_EQUAL(u"Outline"_ustr,
1581 getProperty<OUString>(getParagraph(2), u"NumberingStyleName"_ustr));
1583 // next paragraph: bulleted list item
1585 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1586 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
1587 sNumName = getProperty<OUString>(getParagraph(3), u"NumberingStyleName"_ustr);
1588 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1589 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1591 // third paragraph: normal text without numbering
1593 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1594 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
1595 sNumName = getProperty<OUString>(getParagraph(4), u"NumberingStyleName"_ustr);
1596 CPPUNIT_ASSERT_MESSAGE("Bad numbering", sNumName.isEmpty());
1599 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf140077)
1601 createSwDoc();
1602 SwDoc* const pDoc = getSwDoc();
1604 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
1606 // hide
1607 dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
1609 pWrtShell->Insert(u"a"_ustr);
1610 pWrtShell->SplitNode();
1611 pWrtShell->Insert(u"b"_ustr);
1612 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1613 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1614 // enable
1615 dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
1617 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1618 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1619 CPPUNIT_ASSERT_MESSAGE(
1620 "redlines should be visible",
1621 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1622 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
1624 pWrtShell->Delete();
1625 pWrtShell->SttEndDoc(/*bStart=*/false);
1626 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1627 dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
1629 // crashed in layout
1630 pWrtShell->SplitNode();
1632 pWrtShell->Undo();
1633 pWrtShell->Redo();
1634 pWrtShell->Undo();
1635 pWrtShell->Redo();
1638 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf109376_redline)
1640 createSwDoc();
1641 SwDoc* pDoc = getSwDoc();
1642 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1643 CPPUNIT_ASSERT(pWrtShell);
1644 // need 2 paragraphs to get to the bMoveNds case
1645 pWrtShell->Insert(u"foo"_ustr);
1646 pWrtShell->SplitNode();
1647 pWrtShell->Insert(u"bar"_ustr);
1648 pWrtShell->SplitNode();
1649 pWrtShell->StartOfSection(false);
1651 // add AT_PARA fly at 1st to be deleted node
1652 SwFormatAnchor anchor(RndStdIds::FLY_AT_PARA);
1653 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
1654 SfxItemSet flySet(pDoc->GetAttrPool(),
1655 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
1656 flySet.Put(anchor);
1657 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
1658 flySet.Put(size); // set a size, else we get 1 char per line...
1659 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
1660 CPPUNIT_ASSERT(pFly != nullptr);
1662 pWrtShell->SttEndDoc(false);
1663 SwInsertTableOptions tableOpt(SwInsertTableFlags::DefaultBorder, 0);
1664 const SwTable& rTable = pWrtShell->InsertTable(tableOpt, 1, 1);
1666 pWrtShell->StartOfSection(false);
1667 SwPaM pam(*pWrtShell->GetCursor()->GetPoint());
1668 pam.SetMark();
1669 pam.GetPoint()->Assign(*rTable.GetTableNode());
1670 pam.Exchange(); // same selection direction as in doc compare...
1672 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
1673 rIDRA.SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert | RedlineFlags::ShowDelete);
1674 rIDRA.AppendRedline(new SwRangeRedline(RedlineType::Delete, pam), true);
1675 // this used to assert/crash with m_pAnchoredFlys mismatch because the
1676 // fly was not deleted but its anchor was moved to the SwTableNode
1677 rIDRA.AcceptAllRedline(true);
1679 CPPUNIT_ASSERT_EQUAL(size_t(0), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1680 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1681 rUndoManager.Undo();
1682 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1683 rUndoManager.Redo();
1684 CPPUNIT_ASSERT_EQUAL(size_t(0), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1685 rUndoManager.Undo();
1686 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1689 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf109376)
1691 createSwDoc();
1692 SwDoc* pDoc = getSwDoc();
1693 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1694 CPPUNIT_ASSERT(pWrtShell);
1695 // need 2 paragraphs to get to the bMoveNds case
1696 pWrtShell->Insert(u"foo"_ustr);
1697 pWrtShell->SplitNode();
1698 pWrtShell->Insert(u"bar"_ustr);
1699 pWrtShell->SplitNode();
1700 pWrtShell->StartOfSection(false);
1702 // add AT_PARA fly at 1st to be deleted node
1703 SwFormatAnchor anchor(RndStdIds::FLY_AT_PARA);
1704 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
1705 SfxItemSet flySet(pDoc->GetAttrPool(),
1706 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
1707 flySet.Put(anchor);
1708 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
1709 flySet.Put(size); // set a size, else we get 1 char per line...
1710 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
1711 CPPUNIT_ASSERT(pFly != nullptr);
1713 pWrtShell->SttEndDoc(false);
1714 SwInsertTableOptions tableOpt(SwInsertTableFlags::DefaultBorder, 0);
1715 const SwTable& rTable = pWrtShell->InsertTable(tableOpt, 1, 1);
1717 pWrtShell->StartOfSection(false);
1718 SwPaM pam(*pWrtShell->GetCursor()->GetPoint());
1719 pam.SetMark();
1720 pam.GetPoint()->Assign(*rTable.GetTableNode());
1721 pam.Exchange(); // same selection direction as in doc compare...
1723 // this used to assert/crash with m_pAnchoredFlys mismatch because the
1724 // fly was not deleted but its anchor was moved to the SwTableNode
1725 pDoc->getIDocumentContentOperations().DeleteRange(pam);
1726 CPPUNIT_ASSERT_EQUAL(size_t(0), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1727 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1728 rUndoManager.Undo();
1729 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1730 rUndoManager.Redo();
1731 CPPUNIT_ASSERT_EQUAL(size_t(0), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1732 rUndoManager.Undo();
1733 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1736 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf147414)
1738 createSwDoc();
1739 SwDoc* pDoc = getSwDoc();
1740 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
1741 SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect());
1743 pWrtShell->Insert(u"Abc"_ustr);
1745 // hide and enable
1746 dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
1747 dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
1749 CPPUNIT_ASSERT(pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1750 CPPUNIT_ASSERT(
1751 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1752 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
1754 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1755 // backspace
1756 pWrtShell->DelLeft();
1757 pWrtShell->AutoCorrect(corr, u' ');
1759 // problem was this was 1 i.e. before the deleted "b" while " " was inserted after
1760 CPPUNIT_ASSERT_EQUAL(sal_Int32(3),
1761 pWrtShell->getShellCursor(false)->GetPoint()->GetContentIndex());
1762 CPPUNIT_ASSERT_EQUAL(
1763 u"Ab c"_ustr,
1764 pWrtShell->getShellCursor(false)->GetPoint()->GetNode().GetTextNode()->GetText());
1767 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf147310)
1769 createSwDoc();
1770 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1771 CPPUNIT_ASSERT(pWrtShell);
1773 // somehow bug happens only with 2 tables
1774 SwInsertTableOptions tableOpt(SwInsertTableFlags::DefaultBorder, 0);
1775 pWrtShell->InsertTable(tableOpt, 1, 1);
1776 pWrtShell->InsertTable(tableOpt, 1, 1);
1778 pWrtShell->SttEndDoc(/*bStart=*/true);
1780 pWrtShell->DeleteRow(false);
1781 pWrtShell->DeleteRow(false);
1784 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1785 assertXPath(pXmlDoc, "/root/page/body/tab", 0);
1787 pWrtShell->Undo();
1788 // this did not create frames for the table
1789 pWrtShell->Undo();
1791 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1792 // there are 2 tables
1793 assertXPath(pXmlDoc, "/root/page/body/tab", 2);
1795 pWrtShell->Redo();
1796 pWrtShell->Redo();
1798 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1799 assertXPath(pXmlDoc, "/root/page/body/tab", 0);
1801 pWrtShell->Undo();
1802 pWrtShell->Undo();
1804 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1805 // there are 2 tables
1806 assertXPath(pXmlDoc, "/root/page/body/tab", 2);
1810 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf80194_autoSubscript)
1812 createSwDoc();
1814 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1815 "Automatic mode enabled", false,
1816 getProperty<bool>(getRun(getParagraph(1), 1), u"CharAutoEscapement"_ustr));
1817 dispatchCommand(mxComponent, u".uno:SubScript"_ustr, {});
1818 // Writer has always had automatic mode enabled when creating subscript/superscripts.
1819 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1820 "Automatic mode enabled", true,
1821 getProperty<bool>(getRun(getParagraph(1), 1), u"CharAutoEscapement"_ustr));
1824 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf64242_optimizeTable)
1826 createSwDoc("tdf64242_optimizeTable.odt");
1827 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1829 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1830 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
1831 uno::UNO_QUERY);
1832 uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
1833 uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows();
1835 double origWidth = getProperty<double>(xTextTable, u"Width"_ustr);
1836 sal_Int32 nToleranceW = origWidth * .01;
1837 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table Width", double(17013), origWidth, nToleranceW);
1839 pWrtShell->SelTable(); //select the whole table
1841 dispatchCommand(mxComponent, u".uno:SetOptimalColumnWidth"_ustr, {});
1842 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table Width: optimize", origWidth,
1843 getProperty<double>(xTextTable, u"Width"_ustr),
1844 nToleranceW);
1846 dispatchCommand(mxComponent, u".uno:SetMinimalColumnWidth"_ustr, {});
1847 CPPUNIT_ASSERT_MESSAGE("Table Width: minimized",
1848 (origWidth - nToleranceW)
1849 > getProperty<double>(xTextTable, u"Width"_ustr));
1851 double origRowHeight = getProperty<double>(xTableRows->getByIndex(2), u"Height"_ustr);
1852 sal_Int32 nToleranceH = origRowHeight * .01;
1853 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Row Height", double(3441), origRowHeight, nToleranceH);
1855 dispatchCommand(mxComponent, u".uno:SetOptimalRowHeight"_ustr, {});
1856 double optimalRowHeight = getProperty<double>(xTableRows->getByIndex(2), u"Height"_ustr);
1857 CPPUNIT_ASSERT_MESSAGE("Row Height: optimized",
1858 (origRowHeight - nToleranceH) > optimalRowHeight);
1860 dispatchCommand(mxComponent, u".uno:SetMinimalRowHeight"_ustr, {});
1861 double minimalRowHeight = getProperty<double>(xTableRows->getByIndex(2), u"Height"_ustr);
1862 CPPUNIT_ASSERT_MESSAGE("Row Height: minimized",
1863 (optimalRowHeight - nToleranceH) > minimalRowHeight);
1864 CPPUNIT_ASSERT_EQUAL_MESSAGE("Row set to auto-height", double(0), minimalRowHeight);
1867 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf45525)
1869 createSwDoc("tdf45525.odt");
1870 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1872 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1873 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
1874 uno::UNO_QUERY);
1875 uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
1876 uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows();
1878 CPPUNIT_ASSERT_EQUAL(3889.0, getProperty<double>(xTableRows->getByIndex(0), u"Height"_ustr));
1879 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(1), u"Height"_ustr));
1880 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(2), u"Height"_ustr));
1881 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(3), u"Height"_ustr));
1882 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(4), u"Height"_ustr));
1884 //Select three cells in the first column
1885 pWrtShell->Down(/*bSelect=*/true);
1886 pWrtShell->Down(/*bSelect=*/true);
1888 dispatchCommand(mxComponent, u".uno:SetOptimalRowHeight"_ustr, {});
1890 // Without the fix in place, this test would have failed with
1891 // - Expected: 1914
1892 // - Actual : 3889
1893 CPPUNIT_ASSERT_EQUAL(1914.0, getProperty<double>(xTableRows->getByIndex(0), u"Height"_ustr));
1894 CPPUNIT_ASSERT_EQUAL(1914.0, getProperty<double>(xTableRows->getByIndex(1), u"Height"_ustr));
1895 CPPUNIT_ASSERT_EQUAL(1914.0, getProperty<double>(xTableRows->getByIndex(2), u"Height"_ustr));
1896 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(3), u"Height"_ustr));
1897 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(4), u"Height"_ustr));
1900 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf126784_distributeSelectedColumns)
1902 createSwDoc("tdf126784_distributeSelectedColumns.odt");
1903 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1905 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1906 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
1907 uno::UNO_QUERY);
1908 uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
1909 uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows();
1911 auto aSeq = getProperty<uno::Sequence<text::TableColumnSeparator>>(
1912 xTableRows->getByIndex(0), u"TableColumnSeparators"_ustr);
1913 sal_Int16 nOrigCol2Pos = aSeq[0].Position;
1914 sal_Int16 nOrigCol3Pos = aSeq[1].Position;
1916 //Select column 1 and 2
1917 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1919 dispatchCommand(mxComponent, u".uno:DistributeColumns"_ustr, {});
1921 aSeq = getProperty<uno::Sequence<text::TableColumnSeparator>>(xTableRows->getByIndex(0),
1922 u"TableColumnSeparators"_ustr);
1923 CPPUNIT_ASSERT_MESSAGE("Second column should shrink", nOrigCol2Pos < aSeq[0].Position);
1924 CPPUNIT_ASSERT_EQUAL_MESSAGE("Last column shouldn't change", nOrigCol3Pos, aSeq[1].Position);
1927 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf144317)
1929 createSwDoc("tdf144317.odt");
1930 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1932 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1933 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
1934 uno::UNO_QUERY);
1935 uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
1936 uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows();
1938 auto aSeq = getProperty<uno::Sequence<text::TableColumnSeparator>>(
1939 xTableRows->getByIndex(0), u"TableColumnSeparators"_ustr);
1940 sal_Int16 nOrigCol1Pos = aSeq[0].Position;
1942 // Move the cursor inside the table
1943 pWrtShell->Down(/*bSelect=*/false);
1945 //Select some cells in the first column
1946 pWrtShell->Down(/*bSelect=*/true);
1947 pWrtShell->Down(/*bSelect=*/true);
1948 pWrtShell->Down(/*bSelect=*/true);
1950 dispatchCommand(mxComponent, u".uno:SetMinimalColumnWidth"_ustr, {});
1952 aSeq = getProperty<uno::Sequence<text::TableColumnSeparator>>(xTableRows->getByIndex(0),
1953 u"TableColumnSeparators"_ustr);
1954 CPPUNIT_ASSERT_MESSAGE("First column should shrink", aSeq[0].Position < nOrigCol1Pos);
1957 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf108687_tabstop)
1959 createSwDoc("tdf108687_tabstop.odt");
1960 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1961 SwNodeOffset nStartIndex = pWrtShell->GetCursor()->GetPointNode().GetIndex();
1962 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(9), nStartIndex);
1964 // Now pressing 'tab' should jump to the radio buttons.
1965 SwXTextDocument* pTextDoc = getSwTextDoc();
1966 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
1967 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_TAB);
1968 Scheduler::ProcessEventsToIdle();
1969 //sal_Int32 nEndIndex = pWrtShell->GetCursor()->GetNode().GetIndex();
1970 //CPPUNIT_ASSERT_EQUAL(sal_Int32(11), nEndIndex);
1973 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119571)
1975 createSwDoc("tdf54819.fodt");
1976 SwDoc* pDoc = getSwDoc();
1978 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
1979 getProperty<OUString>(getParagraph(1), u"ParaStyleName"_ustr));
1980 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
1981 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
1983 //turn on red-lining and show changes
1984 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1985 | RedlineFlags::ShowInsert);
1986 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1987 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1988 CPPUNIT_ASSERT_MESSAGE(
1989 "redlines should be visible",
1990 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1992 // join paragraphs by removing the end of the first one with paragraph break
1993 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
1994 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1995 pWrtShell->EndPara(/*bSelect=*/true);
1996 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1997 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
1999 // second paragraph changes its style in "Show changes" mode
2000 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
2001 getProperty<OUString>(getParagraph(1), u"ParaStyleName"_ustr));
2002 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
2003 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
2006 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf144058)
2008 createSwDoc("tdf144058.fodt");
2009 SwDoc* pDoc = getSwDoc();
2011 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
2012 getProperty<OUString>(getParagraph(1), u"ParaStyleName"_ustr));
2014 //turn on red-lining and show changes
2015 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
2016 | RedlineFlags::ShowInsert);
2017 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2018 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2019 CPPUNIT_ASSERT_MESSAGE(
2020 "redlines should be visible",
2021 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2023 // join first and last but one paragraphs by removing the end of the first paragraph
2024 // with paragraph break, and by removing two tables of the selected range completely
2025 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2026 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
2027 pWrtShell->Down(/*bSelect=*/true);
2028 pWrtShell->Down(/*bSelect=*/true);
2029 pWrtShell->Down(/*bSelect=*/true);
2030 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
2032 // accept all: tables are deleted
2033 dispatchCommand(mxComponent, u".uno:AcceptAllTrackedChanges"_ustr, {});
2035 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
2036 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
2037 uno::UNO_QUERY);
2038 // This was 2 (remaining empty tables)
2039 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
2042 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf147507)
2044 createSwDoc("tdf147507.fodt");
2045 SwDoc* pDoc = getSwDoc();
2047 // turn on red-lining and show changes
2048 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
2049 | RedlineFlags::ShowInsert);
2050 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2051 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2052 CPPUNIT_ASSERT_MESSAGE(
2053 "redlines should be visible",
2054 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2056 // select all, backspace and reject all crashed
2057 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
2058 dispatchCommand(mxComponent, u".uno:SwBackSpace"_ustr, {});
2059 dispatchCommand(mxComponent, u".uno:RejectAllTrackedChanges"_ustr, {});
2062 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119019)
2064 // check handling of overlapping redlines
2065 createSwDoc("tdf119019.docx");
2067 CPPUNIT_ASSERT_EQUAL(u"Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus."_ustr,
2068 getParagraph(2)->getString());
2069 CPPUNIT_ASSERT_EQUAL(u""_ustr, getRun(getParagraph(2), 1)->getString());
2070 // second paragraph has got a tracked paragraph formatting at this point
2071 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(2), 1), u"RedlineType"_ustr));
2073 // delete last word of the second paragraph to remove tracked paragraph formatting
2074 // of this paragraph to track and show word deletion correctly.
2075 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2076 pWrtShell->Down(/*bSelect=*/false);
2077 pWrtShell->Down(/*bSelect=*/false);
2078 pWrtShell->Down(/*bSelect=*/false);
2079 pWrtShell->EndPara(/*bSelect=*/false);
2080 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 7, /*bBasicCall=*/false);
2081 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
2083 // check tracked text deletion
2084 CPPUNIT_ASSERT_EQUAL(u"tellus."_ustr, getRun(getParagraph(2), 3)->getString());
2085 CPPUNIT_ASSERT_EQUAL(u""_ustr, getRun(getParagraph(2), 2)->getString());
2086 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(2), 2), u"RedlineType"_ustr));
2088 // make sure that the tracked paragraph formatting is removed
2089 CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(2), 1), u"RedlineType"_ustr));
2092 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119824)
2094 // check handling of overlapping redlines with Redo
2095 createSwDoc("tdf119019.docx");
2096 SwDoc* pDoc = getSwDoc();
2098 CPPUNIT_ASSERT_EQUAL(u"Pellentesque habitant morbi tristique senectus "
2099 "et netus et malesuada fames ac turpis egestas. "
2100 "Proin pharetra nonummy pede. Mauris et orci."_ustr,
2101 getParagraph(3)->getString());
2102 CPPUNIT_ASSERT_EQUAL(u""_ustr, getRun(getParagraph(3), 1)->getString());
2103 // third paragraph has got a tracked paragraph formatting at this point
2104 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 1), u"RedlineType"_ustr));
2106 // and a tracked text deletion at the beginning of the paragraph
2107 CPPUNIT_ASSERT_EQUAL(u"Pellentesque habitant morbi tristique senectus "_ustr,
2108 getRun(getParagraph(3), 3)->getString());
2109 CPPUNIT_ASSERT_EQUAL(u""_ustr, getRun(getParagraph(3), 2)->getString());
2110 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 2), u"RedlineType"_ustr));
2112 // delete last word of the third paragraph to remove tracked paragraph formatting
2113 // of this paragraph to track and show word deletion correctly.
2114 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2115 pWrtShell->Down(/*bSelect=*/false);
2116 pWrtShell->Down(/*bSelect=*/false);
2117 pWrtShell->Down(/*bSelect=*/false);
2118 pWrtShell->Down(/*bSelect=*/false);
2119 pWrtShell->EndPara(/*bSelect=*/false);
2120 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 5, /*bBasicCall=*/false);
2121 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
2123 // check tracking of the new text deletion
2124 CPPUNIT_ASSERT_EQUAL(u"orci."_ustr, getRun(getParagraph(3), 7)->getString());
2125 CPPUNIT_ASSERT_EQUAL(u""_ustr, getRun(getParagraph(3), 6)->getString());
2126 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 6), u"RedlineType"_ustr));
2128 // make sure that the tracked paragraph formatting is removed (tracked deletion is in the second run)
2129 CPPUNIT_ASSERT_EQUAL(u"Pellentesque habitant morbi tristique senectus "_ustr,
2130 getRun(getParagraph(3), 2)->getString());
2131 CPPUNIT_ASSERT_EQUAL(u""_ustr, getRun(getParagraph(3), 1)->getString());
2132 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 1), u"RedlineType"_ustr));
2134 // tdf#119824 check redo
2135 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
2136 rUndoManager.Undo();
2137 rUndoManager.Undo();
2138 rUndoManager.Redo();
2139 rUndoManager.Redo();
2141 // check again the first tracked text deletion (we lost this before the redo fix)
2142 CPPUNIT_ASSERT_EQUAL(u"Pellentesque habitant morbi tristique senectus "_ustr,
2143 getRun(getParagraph(3), 2)->getString());
2144 CPPUNIT_ASSERT_EQUAL(u""_ustr, getRun(getParagraph(3), 1)->getString());
2145 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 1), u"RedlineType"_ustr));
2147 // check redo of the new tracked text deletion
2148 CPPUNIT_ASSERT_EQUAL(u"orci."_ustr, getRun(getParagraph(3), 7)->getString());
2149 CPPUNIT_ASSERT_EQUAL(u""_ustr, getRun(getParagraph(3), 6)->getString());
2150 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 6), u"RedlineType"_ustr));
2153 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf105413)
2155 createSwDoc("tdf105413.fodt");
2156 SwDoc* pDoc = getSwDoc();
2158 // all paragraphs have got Standard paragraph style
2159 for (int i = 1; i < 4; ++i)
2161 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
2162 getProperty<OUString>(getParagraph(i), u"ParaStyleName"_ustr));
2165 // turn on red-lining and show changes
2166 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
2167 | RedlineFlags::ShowDelete);
2168 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2169 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2170 CPPUNIT_ASSERT_MESSAGE(
2171 "redlines should be visible",
2172 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2174 // Set Heading 1 paragraph style in the 3th paragraph.
2175 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2176 pWrtShell->Down(/*bSelect=*/false);
2177 pWrtShell->Down(/*bSelect=*/false);
2178 pWrtShell->EndPara(/*bSelect=*/false);
2180 uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence({
2181 { "Style", uno::Any(u"Heading 1"_ustr) },
2182 { "FamilyName", uno::Any(u"ParagraphStyles"_ustr) },
2184 dispatchCommand(mxComponent, u".uno:StyleApply"_ustr, aPropertyValues);
2186 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
2187 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
2188 CPPUNIT_ASSERT_EQUAL(u"Standard"_ustr,
2189 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
2192 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf76817)
2194 createSwDoc("num-parent-style.docx");
2196 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2197 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
2198 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2199 getProperty<sal_Int32>(getParagraph(2), u"OutlineLevel"_ustr));
2200 CPPUNIT_ASSERT_EQUAL(u"1.1"_ustr,
2201 getProperty<OUString>(getParagraph(2), u"ListLabelString"_ustr));
2203 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2204 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
2205 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2206 getProperty<sal_Int32>(getParagraph(4), u"OutlineLevel"_ustr));
2207 CPPUNIT_ASSERT_EQUAL(u"2.1"_ustr,
2208 getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
2210 // set Heading 2 style of paragraph 2 to Heading 1
2212 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2213 pWrtShell->Down(/*bSelect=*/false);
2215 uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence({
2216 { "Style", uno::Any(u"Heading 1"_ustr) },
2217 { "FamilyName", uno::Any(u"ParagraphStyles"_ustr) },
2219 dispatchCommand(mxComponent, u".uno:StyleApply"_ustr, aPropertyValues);
2221 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
2222 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
2223 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2224 getProperty<sal_Int32>(getParagraph(2), u"OutlineLevel"_ustr));
2225 // This was "1 Heading" instead of "2 Heading"
2226 CPPUNIT_ASSERT_EQUAL(u"2"_ustr,
2227 getProperty<OUString>(getParagraph(2), u"ListLabelString"_ustr));
2229 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2230 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
2231 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2232 getProperty<sal_Int32>(getParagraph(4), u"OutlineLevel"_ustr));
2233 // This was "2.1 Heading"
2234 CPPUNIT_ASSERT_EQUAL(u"3.1"_ustr,
2235 getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
2237 // set Heading 1 style of paragraph 3 to Heading 2
2239 pWrtShell->Down(/*bSelect=*/false);
2241 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
2242 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
2243 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2244 getProperty<sal_Int32>(getParagraph(3), u"OutlineLevel"_ustr));
2245 CPPUNIT_ASSERT_EQUAL(u"3"_ustr,
2246 getProperty<OUString>(getParagraph(3), u"ListLabelString"_ustr));
2248 uno::Sequence<beans::PropertyValue> aPropertyValues2 = comphelper::InitPropertySequence({
2249 { "Style", uno::Any(u"Heading 2"_ustr) },
2250 { "FamilyName", uno::Any(u"ParagraphStyles"_ustr) },
2252 dispatchCommand(mxComponent, u".uno:StyleApply"_ustr, aPropertyValues2);
2254 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2255 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
2256 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2257 getProperty<sal_Int32>(getParagraph(3), u"OutlineLevel"_ustr));
2258 CPPUNIT_ASSERT_EQUAL(u"2.1"_ustr,
2259 getProperty<OUString>(getParagraph(3), u"ListLabelString"_ustr));
2261 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2262 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
2263 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2264 getProperty<sal_Int32>(getParagraph(4), u"OutlineLevel"_ustr));
2265 CPPUNIT_ASSERT_EQUAL(u"2.2"_ustr,
2266 getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
2269 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf76817_round_trip)
2271 createSwDoc("tdf76817.fodt");
2273 // save it to DOCX
2274 saveAndReload(u"Office Open XML Text"_ustr);
2276 SwViewShell* pViewShell = getSwDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
2277 pViewShell->Reformat();
2279 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2280 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
2281 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2282 getProperty<sal_Int32>(getParagraph(2), u"OutlineLevel"_ustr));
2283 CPPUNIT_ASSERT_EQUAL(u"1.1"_ustr,
2284 getProperty<OUString>(getParagraph(2), u"ListLabelString"_ustr));
2286 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2287 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
2288 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2289 getProperty<sal_Int32>(getParagraph(4), u"OutlineLevel"_ustr));
2290 CPPUNIT_ASSERT_EQUAL(u"2.1"_ustr,
2291 getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
2293 // set Heading 2 style of paragraph 2 to Heading 1
2295 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2296 pWrtShell->Down(/*bSelect=*/false);
2298 uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence({
2299 { "Style", uno::Any(u"Heading 1"_ustr) },
2300 { "FamilyName", uno::Any(u"ParagraphStyles"_ustr) },
2302 dispatchCommand(mxComponent, u".uno:StyleApply"_ustr, aPropertyValues);
2304 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
2305 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
2306 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2307 getProperty<sal_Int32>(getParagraph(2), u"OutlineLevel"_ustr));
2308 // This was "1 Heading" instead of "2 Heading"
2309 CPPUNIT_ASSERT_EQUAL(u"2"_ustr,
2310 getProperty<OUString>(getParagraph(2), u"ListLabelString"_ustr));
2312 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2313 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
2314 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2315 getProperty<sal_Int32>(getParagraph(4), u"OutlineLevel"_ustr));
2316 // This was "2.1 Heading"
2317 CPPUNIT_ASSERT_EQUAL(u"3.1"_ustr,
2318 getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
2320 // set Heading 1 style of paragraph 3 to Heading 2
2322 pWrtShell->Down(/*bSelect=*/false);
2324 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
2325 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
2326 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2327 getProperty<sal_Int32>(getParagraph(3), u"OutlineLevel"_ustr));
2328 CPPUNIT_ASSERT_EQUAL(u"3"_ustr,
2329 getProperty<OUString>(getParagraph(3), u"ListLabelString"_ustr));
2331 uno::Sequence<beans::PropertyValue> aPropertyValues2 = comphelper::InitPropertySequence({
2332 { "Style", uno::Any(u"Heading 2"_ustr) },
2333 { "FamilyName", uno::Any(u"ParagraphStyles"_ustr) },
2335 dispatchCommand(mxComponent, u".uno:StyleApply"_ustr, aPropertyValues2);
2337 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2338 getProperty<OUString>(getParagraph(3), u"ParaStyleName"_ustr));
2339 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2340 getProperty<sal_Int32>(getParagraph(3), u"OutlineLevel"_ustr));
2341 CPPUNIT_ASSERT_EQUAL(u"2.1"_ustr,
2342 getProperty<OUString>(getParagraph(3), u"ListLabelString"_ustr));
2344 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2345 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
2346 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2347 getProperty<sal_Int32>(getParagraph(4), u"OutlineLevel"_ustr));
2348 CPPUNIT_ASSERT_EQUAL(u"2.2"_ustr,
2349 getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
2352 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf76817_custom_outline)
2354 createSwDoc("tdf76817.docx");
2356 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
2357 getProperty<OUString>(getParagraph(1), u"ParaStyleName"_ustr));
2358 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2359 getProperty<sal_Int32>(getParagraph(1), u"OutlineLevel"_ustr));
2360 CPPUNIT_ASSERT_EQUAL(u"1"_ustr,
2361 getProperty<OUString>(getParagraph(1), u"ListLabelString"_ustr));
2363 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2364 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
2365 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2366 getProperty<sal_Int32>(getParagraph(2), u"OutlineLevel"_ustr));
2367 // This wasn't numbered
2368 CPPUNIT_ASSERT_EQUAL(u"1.1"_ustr,
2369 getProperty<OUString>(getParagraph(2), u"ListLabelString"_ustr));
2371 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2372 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
2373 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2374 getProperty<sal_Int32>(getParagraph(4), u"OutlineLevel"_ustr));
2375 // This wasn't numbered
2376 CPPUNIT_ASSERT_EQUAL(u"2.1"_ustr,
2377 getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
2379 // set Heading 2 style of paragraph 2 to Heading 1
2381 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2382 pWrtShell->Down(/*bSelect=*/false);
2384 uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence({
2385 { "Style", uno::Any(u"Heading 1"_ustr) },
2386 { "FamilyName", uno::Any(u"ParagraphStyles"_ustr) },
2388 dispatchCommand(mxComponent, u".uno:StyleApply"_ustr, aPropertyValues);
2390 CPPUNIT_ASSERT_EQUAL(u"Heading 1"_ustr,
2391 getProperty<OUString>(getParagraph(2), u"ParaStyleName"_ustr));
2392 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2393 getProperty<sal_Int32>(getParagraph(2), u"OutlineLevel"_ustr));
2394 CPPUNIT_ASSERT_EQUAL(u"2"_ustr,
2395 getProperty<OUString>(getParagraph(2), u"ListLabelString"_ustr));
2397 CPPUNIT_ASSERT_EQUAL(u"Heading 2"_ustr,
2398 getProperty<OUString>(getParagraph(4), u"ParaStyleName"_ustr));
2399 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2400 getProperty<sal_Int32>(getParagraph(4), u"OutlineLevel"_ustr));
2401 // This wasn't numbered
2402 CPPUNIT_ASSERT_EQUAL(u"3.1"_ustr,
2403 getProperty<OUString>(getParagraph(4), u"ListLabelString"_ustr));
2406 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf123102)
2408 createSwDoc("tdf123102.odt");
2409 // insert a new row after a vertically merged cell
2410 dispatchCommand(mxComponent, u".uno:InsertRowsAfter"_ustr, {});
2411 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
2412 // This was "3." - caused by the hidden numbered paragraph of the new merged cell
2413 assertXPath(pXmlDoc,
2414 "/root/page/body/tab/row[6]/cell[1]/txt/SwParaPortion/SwLineLayout/SwFieldPortion",
2415 "expand", u"2.");
2418 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testUnfloatButtonSmallTable)
2420 // The floating table in the test document is too small, so we don't provide an unfloat button
2421 createSwDoc("small_floating_table.odt");
2422 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2423 CPPUNIT_ASSERT(pWrtShell);
2425 const SwSortedObjs* pAnchored
2426 = pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs();
2427 CPPUNIT_ASSERT(pAnchored);
2428 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pAnchored->size());
2429 SwAnchoredObject* pAnchoredObj = (*pAnchored)[0];
2431 SwFlyFrame* pFlyFrame = pAnchoredObj->DynCastFlyFrame();
2432 CPPUNIT_ASSERT(pFlyFrame);
2433 CPPUNIT_ASSERT(!pFlyFrame->IsShowUnfloatButton(pWrtShell));
2435 SdrObject* pObj = pFlyFrame->GetFormat()->FindRealSdrObject();
2436 CPPUNIT_ASSERT(pObj);
2437 pWrtShell->SelectObj(Point(), 0, pObj);
2438 CPPUNIT_ASSERT(!pFlyFrame->IsShowUnfloatButton(pWrtShell));
2441 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testUnfloatButton)
2443 // Different use cases where unfloat button should be visible
2444 const std::vector<OUString> aTestFiles = {
2445 u"unfloatable_floating_table.odt"_ustr, // Typical use case of multipage floating table
2448 for (const OUString& aTestFile : aTestFiles)
2450 OString sTestFileName = OUStringToOString(aTestFile, RTL_TEXTENCODING_UTF8);
2451 OString sFailureMessage = OString::Concat("Failure in the test file: ") + sTestFileName;
2453 createSwDoc(sTestFileName.getStr());
2454 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2455 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pWrtShell);
2457 const SwSortedObjs* pAnchored;
2458 pAnchored = pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs();
2459 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pAnchored);
2460 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailureMessage.getStr(), static_cast<size_t>(1),
2461 pAnchored->size());
2462 SwAnchoredObject* pAnchoredObj = (*pAnchored)[0];
2464 // The unfloat button is not visible until it gets selected
2465 SwFlyFrame* pFlyFrame = pAnchoredObj->DynCastFlyFrame();
2466 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pFlyFrame);
2467 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(),
2468 !pFlyFrame->IsShowUnfloatButton(pWrtShell));
2470 SdrObject* pObj = pFlyFrame->GetFormat()->FindRealSdrObject();
2471 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pObj);
2472 pWrtShell->SelectObj(Point(), 0, pObj);
2473 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pFlyFrame->IsShowUnfloatButton(pWrtShell));
2477 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testUnfloatButtonReadOnlyMode)
2479 // In read only mode we don't show the unfloat button even if we have a multipage floating table
2480 createSwDoc("unfloatable_floating_table.odt");
2481 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2482 CPPUNIT_ASSERT(pWrtShell);
2483 pWrtShell->SetReadonlyOption(true);
2485 const SwSortedObjs* pAnchored
2486 = pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs();
2487 CPPUNIT_ASSERT(pAnchored);
2488 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pAnchored->size());
2489 SwAnchoredObject* pAnchoredObj = (*pAnchored)[0];
2491 SwFlyFrame* pFlyFrame = pAnchoredObj->DynCastFlyFrame();
2492 CPPUNIT_ASSERT(pFlyFrame);
2493 CPPUNIT_ASSERT(!pFlyFrame->IsShowUnfloatButton(pWrtShell));
2495 SdrObject* pObj = pFlyFrame->GetFormat()->FindRealSdrObject();
2496 CPPUNIT_ASSERT(pObj);
2497 pWrtShell->SelectObj(Point(), 0, pObj);
2498 CPPUNIT_ASSERT(!pFlyFrame->IsShowUnfloatButton(pWrtShell));
2501 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testUnfloating)
2503 // Test unfloating with tables imported from different file formats
2504 const std::vector<OUString> aTestFiles = {
2505 u"unfloatable_floating_table.odt"_ustr,
2508 for (const OUString& aTestFile : aTestFiles)
2510 OString sTestFileName = OUStringToOString(aTestFile, RTL_TEXTENCODING_UTF8);
2511 OString sFailureMessage = OString::Concat("Failure in the test file: ") + sTestFileName;
2513 // Test what happens when pushing the unfloat button
2514 createSwDoc(sTestFileName.getStr());
2515 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2516 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pWrtShell);
2518 SwFlyFrame* pFlyFrame;
2520 // Before unfloating we have only one page with a fly frame
2522 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailureMessage.getStr(), SwFrameType::Page,
2523 pWrtShell->GetLayout()->GetLower()->GetType());
2524 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(),
2525 !pWrtShell->GetLayout()->GetLower()->GetNext());
2526 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2527 sFailureMessage.getStr(), SwFrameType::Txt,
2528 pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetType());
2529 const SwSortedObjs* pAnchored
2530 = pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs();
2531 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pAnchored);
2532 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailureMessage.getStr(), static_cast<size_t>(1),
2533 pAnchored->size());
2534 SwAnchoredObject* pAnchoredObj = (*pAnchored)[0];
2535 pFlyFrame = pAnchoredObj->DynCastFlyFrame();
2536 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pFlyFrame);
2539 // Select the floating table
2540 SdrObject* pObj = pFlyFrame->GetFormat()->FindRealSdrObject();
2541 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pObj);
2542 pWrtShell->SelectObj(Point(), 0, pObj);
2543 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pFlyFrame->IsShowUnfloatButton(pWrtShell));
2545 // Push the unfloat button
2546 pFlyFrame->ActiveUnfloatButton(pWrtShell);
2547 Scheduler::ProcessEventsToIdle();
2549 // After unfloating we have two pages with one table frame on each page
2550 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(),
2551 pWrtShell->GetLayout()->GetLower()->GetNext());
2552 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailureMessage.getStr(), SwFrameType::Page,
2553 pWrtShell->GetLayout()->GetLower()->GetNext()->GetType());
2554 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(),
2555 !pWrtShell->GetLayout()->GetLower()->GetNext()->GetNext());
2556 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2557 sFailureMessage.getStr(), SwFrameType::Tab,
2558 pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetType());
2559 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2560 sFailureMessage.getStr(), SwFrameType::Tab,
2561 pWrtShell->GetLayout()->GetLower()->GetNext()->GetLower()->GetLower()->GetType());
2565 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRTLparaStyle_LocaleArabic)
2567 // New documents, created in RTL locales, were not round-tripping the paragraph style as RTL.
2568 // Set the locale to "ar" for this test.
2569 m_aSavedSettings = Application::GetSettings();
2570 AllSettings aSettings(m_aSavedSettings);
2571 aSettings.SetLanguageTag(LanguageTag(u"ar"_ustr));
2572 Application::SetSettings(aSettings);
2573 comphelper::ScopeGuard g([this] { Application::SetSettings(this->m_aSavedSettings); });
2575 createSwDoc(); // new, empty doc - everything defaults to RTL with Arabic locale
2577 // Save it and load it back.
2578 saveAndReload(u"Office Open XML Text"_ustr);
2580 uno::Reference<beans::XPropertySet> xPageStyle(
2581 getStyles(u"ParagraphStyles"_ustr)->getByName(u"Standard"_ustr), uno::UNO_QUERY_THROW);
2582 // Test the text Direction value for the -none- based paragraph styles
2583 CPPUNIT_ASSERT_EQUAL_MESSAGE("RTL Writing Mode", sal_Int32(1),
2584 getProperty<sal_Int32>(xPageStyle, u"WritingMode"_ustr));
2587 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf122893)
2589 createSwDoc("tdf105413.fodt");
2590 SwDoc* pDoc = getSwDoc();
2592 // all paragraphs are left-aligned with preset single line spacing
2593 for (int i = 1; i < 4; ++i)
2595 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
2596 getProperty<sal_Int32>(getParagraph(i), u"ParaAdjust"_ustr));
2597 dispatchCommand(mxComponent, u".uno:SpacePara1"_ustr, {});
2600 // turn on red-lining and show changes
2601 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
2602 | RedlineFlags::ShowDelete);
2603 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2604 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2605 CPPUNIT_ASSERT_MESSAGE(
2606 "redlines should be visible",
2607 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2609 // Set center-aligned paragraph with preset double line spacing in the 3th paragraph.
2610 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2611 pWrtShell->Down(/*bSelect=*/false);
2612 pWrtShell->Down(/*bSelect=*/false);
2613 pWrtShell->EndPara(/*bSelect=*/false);
2615 dispatchCommand(mxComponent, u".uno:CenterPara"_ustr, {});
2616 dispatchCommand(mxComponent, u".uno:SpacePara2"_ustr, {});
2618 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), getProperty<sal_Int32>(
2619 getParagraph(3), u"ParaAdjust"_ustr)); // center-aligned
2620 CPPUNIT_ASSERT_EQUAL(sal_Int16(200),
2621 getProperty<style::LineSpacing>(getParagraph(3), u"ParaLineSpacing"_ustr)
2622 .Height); // double line spacing
2623 CPPUNIT_ASSERT_EQUAL(
2624 sal_Int32(0), getProperty<sal_Int32>(getParagraph(2), u"ParaAdjust"_ustr)); // left-aligned
2625 CPPUNIT_ASSERT_EQUAL(sal_Int16(100),
2626 getProperty<style::LineSpacing>(getParagraph(2), u"ParaLineSpacing"_ustr)
2627 .Height); // single line spacing
2630 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf122901)
2632 createSwDoc("tdf105413.fodt");
2633 SwDoc* pDoc = getSwDoc();
2635 // all paragraphs with zero borders
2636 for (int i = 1; i < 4; ++i)
2638 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
2639 getProperty<sal_Int32>(getParagraph(i), u"ParaTopMargin"_ustr));
2640 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
2641 getProperty<sal_Int32>(getParagraph(i), u"ParaBottomMargin"_ustr));
2644 // turn on red-lining and show changes
2645 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
2646 | RedlineFlags::ShowDelete);
2647 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2648 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2649 CPPUNIT_ASSERT_MESSAGE(
2650 "redlines should be visible",
2651 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2653 // Increase paragraph borders in the 3th paragraph, similar to the default icon of the UI
2654 // "Increase Paragraph Spacing".
2655 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2656 pWrtShell->Down(/*bSelect=*/false);
2657 pWrtShell->Down(/*bSelect=*/false);
2658 pWrtShell->EndPara(/*bSelect=*/false);
2660 dispatchCommand(mxComponent, u".uno:ParaspaceIncrease"_ustr, {});
2662 CPPUNIT_ASSERT_EQUAL(sal_Int32(101),
2663 getProperty<sal_Int32>(getParagraph(3), u"ParaTopMargin"_ustr));
2664 CPPUNIT_ASSERT_EQUAL(sal_Int32(101),
2665 getProperty<sal_Int32>(getParagraph(3), u"ParaBottomMargin"_ustr));
2666 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
2667 getProperty<sal_Int32>(getParagraph(2), u"ParaTopMargin"_ustr));
2668 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
2669 getProperty<sal_Int32>(getParagraph(2), u"ParaBottomMargin"_ustr));
2672 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf122942)
2674 createSwDoc("tdf122942.odt");
2675 SwDoc* pDoc = getSwDoc();
2676 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
2678 // Do the moral equivalent of mouse button down, move and up.
2679 // Start creating a custom shape that overlaps with the rounded rectangle
2680 // already present in the document.
2681 Point aStartPos(8000, 3000);
2682 pWrtShell->BeginCreate(SdrObjKind::CustomShape, aStartPos);
2684 // Set its size.
2685 Point aMovePos(10000, 5000);
2686 pWrtShell->MoveCreate(aMovePos);
2688 // Finish creation.
2689 pWrtShell->EndCreate(SdrCreateCmd::ForceEnd);
2691 // Make sure that the shape is inserted.
2692 const auto& rFormats = *pDoc->GetSpzFrameFormats();
2693 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rFormats.size());
2695 saveAndReload(u"writer8"_ustr);
2696 pDoc = getSwDoc();
2697 const auto& rFormats2 = *pDoc->GetSpzFrameFormats();
2698 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rFormats2.size());
2700 // Make sure the top of the inserted shape does not move outside the existing shape, even after
2701 // reload.
2702 SdrObject* pObject1 = rFormats2[0]->FindSdrObject();
2703 CPPUNIT_ASSERT(pObject1);
2704 const tools::Rectangle& rOutRect1 = pObject1->GetLastBoundRect();
2705 SdrObject* pObject2 = rFormats2[1]->FindSdrObject();
2706 CPPUNIT_ASSERT(pObject2);
2707 const tools::Rectangle& rOutRect2 = pObject2->GetLastBoundRect();
2708 CPPUNIT_ASSERT(rOutRect2.Top() > rOutRect1.Top());
2709 CPPUNIT_ASSERT(rOutRect2.Top() < rOutRect1.Bottom());
2712 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf132160)
2714 createSwDoc("tdf132160.odt");
2716 // this would crash due to delete redline starting with ToX
2717 dispatchCommand(mxComponent, u".uno:RejectAllTrackedChanges"_ustr, {});
2719 // this would crash due to insert redline ending on table node
2720 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
2722 dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
2724 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
2727 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137526)
2729 createSwDoc("tdf132160.odt");
2731 // switch on "Show changes in margin" mode
2732 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
2734 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
2735 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2737 // select and delete a word
2738 dispatchCommand(mxComponent, u".uno:WordRightSel"_ustr, {});
2739 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
2740 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("support"));
2742 // this would crash due to bad redline range
2743 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
2744 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Encryption"));
2746 // switch off "Show changes in margin" mode
2747 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
2748 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2751 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137684)
2753 createSwDoc("tdf132160.odt");
2755 // switch on "Show changes in margin" mode
2756 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
2758 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
2759 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2761 // select and delete a word letter by letter
2762 for (int i = 0; i <= 10; ++i)
2764 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
2766 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("support"));
2768 // this would crash due to bad redline range
2769 for (int i = 0; i <= 10; ++i)
2771 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
2773 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Encryption "));
2775 // switch off "Show changes in margin" mode
2776 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
2777 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2780 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137503)
2782 createSwDoc("tdf132160.odt");
2784 // switch on "Show changes in margin" mode
2785 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
2787 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
2788 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2790 // select and delete the first two paragraphs
2791 pWrtShell->EndPara(/*bSelect=*/true);
2792 pWrtShell->EndPara(/*bSelect=*/true);
2793 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
2794 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
2795 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("The"));
2797 // this would crash due to bad redline range
2798 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
2799 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Encryption "));
2801 // this would crash due to bad redline range
2802 dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
2803 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("The"));
2805 // switch off "Show changes in margin" mode
2806 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
2807 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2810 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf138605)
2812 createSwDoc();
2813 SwDoc* pDoc = getSwDoc();
2814 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
2816 // turn on red-lining and show changes
2817 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
2818 | RedlineFlags::ShowDelete);
2819 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2820 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2821 CPPUNIT_ASSERT_MESSAGE(
2822 "redlines should be visible",
2823 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2825 // insert a word, delete it with change tracking and try to undo it
2826 pWrtShell->Insert(u"word"_ustr);
2827 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
2828 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
2829 // this crashed due to bad access to the empty redline table
2830 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
2832 // more Undo
2833 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("word"));
2834 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
2835 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith(""));
2836 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
2839 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf138135)
2841 createSwDoc("tdf132160.odt");
2843 // switch on "Show changes in margin" mode
2844 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
2846 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
2847 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2849 // select and delete a word letter by letter by using backspace
2850 dispatchCommand(mxComponent, u".uno:GoToNextWord"_ustr, {});
2852 for (int i = 0; i <= 10; ++i)
2854 dispatchCommand(mxComponent, u".uno:SwBackspace"_ustr, {});
2856 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("support"));
2858 // TODO group redlines for managing tracked changes/showing in margin
2859 for (int i = 0; i <= 10; ++i)
2860 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
2862 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Encryption"));
2864 // switch off "Show changes in margin" mode
2865 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
2866 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2869 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf52391)
2871 createSwDoc("tdf52391.fodt");
2873 dispatchCommand(mxComponent, u".uno:RejectAllTrackedChanges"_ustr, {});
2875 const uno::Reference<text::XTextRange> xRun = getRun(getParagraph(1), 1);
2876 // this was "Portion1", because the tracked background color of Portion1 was
2877 // accepted for "Reject All". Now rejection clears formatting of the text
2878 // in format-only changes, concatenating the text portions in the first paragraph.
2879 CPPUNIT_ASSERT_EQUAL(u"Portion1Portion2"_ustr, xRun->getString());
2882 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137771)
2884 createSwDoc("tdf132160.odt");
2886 // switch on "Show changes in margin" mode
2887 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
2889 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
2890 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2892 // delete a word at the end of the paragraph.
2893 dispatchCommand(mxComponent, u".uno:GotoEndOfPara"_ustr, {});
2894 for (int i = 0; i < 6; ++i)
2896 dispatchCommand(mxComponent, u".uno:SwBackspace"_ustr, {});
2899 CPPUNIT_ASSERT(getParagraph(1)->getString().endsWith("to be "));
2901 // Dump the rendering of the first page as an XML file.
2902 SwDocShell* pShell = getSwDocShell();
2903 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
2904 MetafileXmlDump dumper;
2905 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
2906 CPPUNIT_ASSERT(pXmlDoc);
2908 // This would be 5 without the new vertical redline mark
2909 assertXPath(pXmlDoc, "/metafile/push/push/push/line", 6);
2911 // This was the content of the next <text> (missing deletion on margin)
2912 // or only the first character of the deleted character sequence
2913 assertXPathContent(pXmlDoc, "/metafile/push/push/push/textarray[9]/text", u" saved.");
2915 // this would crash due to bad redline range
2916 for (int i = 0; i < 6; ++i)
2918 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
2920 CPPUNIT_ASSERT(getParagraph(1)->getString().endsWith("to be saved."));
2922 // switch off "Show changes in margin" mode
2923 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
2924 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2927 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf142130)
2929 createSwDoc("tdf142130.fodt");
2930 SwDoc* pDoc = getSwDoc();
2932 //turn on red-lining and show changes
2933 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
2934 | RedlineFlags::ShowInsert);
2935 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2936 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2937 CPPUNIT_ASSERT_MESSAGE(
2938 "redlines should be visible",
2939 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2941 // Dump the rendering of the first page as an XML file.
2942 SwDocShell* pShell = getSwDocShell();
2943 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
2944 MetafileXmlDump dumper;
2945 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
2946 CPPUNIT_ASSERT(pXmlDoc);
2948 // This was 6 (bad crossing out of the first, not deleted image)
2949 // (4 lines = 2 lines for crossing out of the second image + 2 lines =
2950 // vertical "changed line" indicator before the two paragraph lines)
2951 assertXPath(pXmlDoc, "/metafile/push/push/push/line", 4);
2953 // check line color
2954 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[1]/linecolor", 5);
2955 // tdf#142128 This was 3 (NON_PRINTING_CHARACTER_COLOR = #268bd2)
2956 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[1]/linecolor[@color='#268bd2']", 0);
2958 // reject deletion of the second image
2959 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
2960 rIDRA.AcceptAllRedline(false);
2962 xMetaFile = pShell->GetPreviewMetaFile();
2963 xmlDocUniquePtr pXmlDoc2 = dumpAndParse(dumper, *xMetaFile);
2964 // no crossing out and vertical redlines
2965 assertXPath(pXmlDoc2, "/metafile/push/push/push/line", 0);
2968 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf142196)
2970 createSwDoc("tdf142196.fodt");
2971 SwDoc* pDoc = getSwDoc();
2973 //turn on red-lining and show changes
2974 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
2975 | RedlineFlags::ShowInsert);
2976 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2977 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2978 CPPUNIT_ASSERT_MESSAGE(
2979 "redlines should be visible",
2980 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2982 // Dump the rendering of the first page as an XML file.
2983 SwDocShell* pShell = getSwDocShell();
2984 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
2985 MetafileXmlDump dumper;
2987 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
2988 CPPUNIT_ASSERT(pXmlDoc);
2990 // This was 1 (missing crossing out of the deleted image)
2991 // (2 lines = crossing out of the deleted image + 1 line for the
2992 // vertical "changed line" indicator before the paragraph line)
2993 assertXPath(pXmlDoc, "//line", 3);
2995 // check line color
2996 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/linecolor", 1);
2997 // tdf#142128 This was NON_PRINTING_CHARACTER_COLOR (#268bd2)
2998 assertXPath(
2999 pXmlDoc,
3000 "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/linecolor[@color='#268bd2']", 0);
3002 // reject deletion of the image
3003 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
3004 rIDRA.AcceptAllRedline(false);
3006 xMetaFile = pShell->GetPreviewMetaFile();
3007 xmlDocUniquePtr pXmlDoc2 = dumpAndParse(dumper, *xMetaFile);
3009 // no crossing out and vertical "changed line" indicator
3010 assertXPath(pXmlDoc2, "//line", 0);
3013 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf142700)
3015 createSwDoc("tdf142700.fodt");
3016 SwDoc* pDoc = getSwDoc();
3018 //turn on red-lining and show changes
3019 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
3020 | RedlineFlags::ShowInsert);
3021 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3022 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
3023 CPPUNIT_ASSERT_MESSAGE(
3024 "redlines should be visible",
3025 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
3027 // Dump the rendering of the first page as an XML file.
3028 SwDocShell* pShell = getSwDocShell();
3029 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
3030 MetafileXmlDump dumper;
3032 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
3033 CPPUNIT_ASSERT(pXmlDoc);
3035 // (2 lines = crossing out of the deleted image + 1 line for the
3036 // vertical "changed line" indicator before the paragraph line)
3037 assertXPath(pXmlDoc, "//line", 3);
3039 // check line color
3040 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/linecolor", 1);
3041 // tdf#142128 This was NON_PRINTING_CHARACTER_COLOR (#268bd2)
3042 assertXPath(
3043 pXmlDoc,
3044 "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/linecolor[@color='#268bd2']", 0);
3046 // reject deletion of the image
3047 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
3048 rIDRA.AcceptAllRedline(false);
3050 xMetaFile = pShell->GetPreviewMetaFile();
3051 xmlDocUniquePtr pXmlDoc2 = dumpAndParse(dumper, *xMetaFile);
3053 // no crossing out and vertical "changed line" indicator
3054 // This was 2 (not removed strikethrough)
3055 assertXPath(pXmlDoc2, "//line", 0);
3058 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf139120)
3060 createSwDoc("tdf54819.fodt");
3061 SwDoc* pDoc = getSwDoc();
3063 // switch on "Show changes in margin" mode
3064 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
3066 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
3067 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3069 // turn on red-lining and show changes
3070 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
3071 | RedlineFlags::ShowDelete);
3072 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3073 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
3074 CPPUNIT_ASSERT_MESSAGE(
3075 "redlines should be visible",
3076 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
3078 // delete paragraph break
3079 dispatchCommand(mxComponent, u".uno:GotoEndOfPara"_ustr, {});
3080 for (int i = 0; i < 6; ++i)
3082 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
3085 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
3086 CPPUNIT_ASSERT_EQUAL(u"Lorem ipsum sit amet."_ustr, xTextDocument->getText()->getString());
3088 for (int i = 0; i < 6; ++i)
3090 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
3093 CPPUNIT_ASSERT_EQUAL(u"Lorem ipsum"_ustr, getParagraph(1)->getString());
3094 CPPUNIT_ASSERT_EQUAL(u"dolor sit amet."_ustr, getParagraph(2)->getString());
3096 // Dump the rendering of the first page as an XML file.
3097 SwDocShell* pShell = getSwDocShell();
3098 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
3099 MetafileXmlDump dumper;
3100 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
3101 CPPUNIT_ASSERT(pXmlDoc);
3103 // This was the 3, containing the text "$2" instead of nothing
3104 assertXPath(pXmlDoc, "/metafile/push/push/push/textarray", 2);
3106 // switch off "Show changes in margin" mode
3107 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
3108 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3111 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testJoinParaChangesInMargin)
3113 createSwDoc("tdf54819.fodt");
3114 SwDoc* pDoc = getSwDoc();
3116 // switch on "Show changes in margin" mode
3117 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
3119 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
3120 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3122 // turn on red-lining and show changes
3123 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
3124 | RedlineFlags::ShowDelete);
3125 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3126 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
3127 CPPUNIT_ASSERT_MESSAGE(
3128 "redlines should be visible",
3129 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
3131 // delete a character and the paragraph break at the end of the paragraph
3132 dispatchCommand(mxComponent, u".uno:GotoEndOfPara"_ustr, {});
3133 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
3134 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
3135 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
3136 CPPUNIT_ASSERT_EQUAL(u"Lorem ipsudolor sit amet."_ustr, getParagraph(1)->getString());
3138 // Undo
3139 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
3140 // this would crash due to bad redline range
3141 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
3142 CPPUNIT_ASSERT_EQUAL(u"Lorem ipsum"_ustr, getParagraph(1)->getString());
3144 // switch off "Show changes in margin" mode
3145 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
3146 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3149 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf140757)
3151 createSwDoc("tdf54819.fodt");
3152 SwDoc* pDoc = getSwDoc();
3154 // switch on "Show changes in margin" mode
3155 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
3157 SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
3158 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3160 // turn on red-lining and show changes
3161 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
3162 | RedlineFlags::ShowDelete);
3163 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3164 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
3165 CPPUNIT_ASSERT_MESSAGE(
3166 "redlines should be visible",
3167 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
3169 // delete a character in the first paragraph, and another character in the second one
3170 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
3171 pWrtShell->Down(/*bSelect=*/false);
3172 dispatchCommand(mxComponent, u".uno:Delete"_ustr, {});
3174 CPPUNIT_ASSERT_EQUAL(u"orem ipsum"_ustr, getParagraph(1)->getString());
3175 CPPUNIT_ASSERT_EQUAL(u"olor sit amet."_ustr, getParagraph(2)->getString());
3177 // accept all changes
3178 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
3179 rIDRA.AcceptAllRedline(/*bAccept=*/true);
3181 CPPUNIT_ASSERT_EQUAL(u"orem ipsum"_ustr, getParagraph(1)->getString());
3182 CPPUNIT_ASSERT_EQUAL(u"olor sit amet."_ustr, getParagraph(2)->getString());
3184 // This crashed
3185 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
3187 // Check result of Undo
3188 rIDRA.AcceptAllRedline(/*bAccept=*/false);
3189 CPPUNIT_ASSERT_EQUAL(u"Lorem ipsum"_ustr, getParagraph(1)->getString());
3190 CPPUNIT_ASSERT_EQUAL(u"dolor sit amet."_ustr, getParagraph(2)->getString());
3192 // switch off "Show changes in margin" mode
3193 dispatchCommand(mxComponent, u".uno:ShowChangesInMargin"_ustr, {});
3194 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3197 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testConditionalHiddenSectionIssue)
3199 // tdf#54703
3200 // When exporting the bug document as PDF, the conditional hidden
3201 // sections became visible in the PDF and in the document.
3203 std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
3204 if (!pPDFium)
3205 return;
3207 createSwDoc("HiddenSection.odt");
3208 SwDoc* pDoc = getSwDoc();
3210 // Check section conditional hidden status - all should be hidden (IsCondHidden == true)
3211 for (SwNodeOffset i(0); i < pDoc->GetNodes().Count(); ++i)
3213 if (SwSectionNode const* const pNode = pDoc->GetNodes()[i]->GetSectionNode())
3215 CPPUNIT_ASSERT_EQUAL(true, pNode->GetSection().IsCondHidden());
3219 // PDF export
3220 save(u"writer_pdf_Export"_ustr);
3222 auto pPdfDocument = parsePDFExport();
3223 auto pPdfPage = pPdfDocument->openPage(0);
3224 CPPUNIT_ASSERT(pPdfPage);
3226 // No PDF object should be present in the page - sections remained hidden
3227 CPPUNIT_ASSERT_EQUAL(0, pPdfPage->getObjectCount());
3229 // Check section conditional hidden status - all should remained hidden (IsCondHidden == true)
3230 for (SwNodeOffset i(0); i < pDoc->GetNodes().Count(); ++i)
3232 if (SwSectionNode const* const pNode = pDoc->GetNodes()[i]->GetSectionNode())
3234 CPPUNIT_ASSERT_EQUAL(true, pNode->GetSection().IsCondHidden());
3239 CPPUNIT_PLUGIN_IMPLEMENT();
3241 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */