android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / qa / extras / uiwriter / uiwriter2.cxx
blob6c9714367bf7774f4278b97fabb92bd5e0c2c199
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("/sw/qa/extras/uiwriter/data/")
54 protected:
55 AllSettings m_aSavedSettings;
58 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf47471_paraStyleBackground)
60 createSwDoc("tdf47471_paraStyleBackground.odt");
61 SwDoc* pDoc = getSwDoc();
62 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
64 CPPUNIT_ASSERT_EQUAL(OUString("00Background"),
65 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
66 CPPUNIT_ASSERT_EQUAL(Color(0xe0c2cd), getProperty<Color>(getParagraph(2), "FillColor"));
68 pWrtShell->EndPara(/*bSelect=*/true);
69 pWrtShell->EndPara(/*bSelect=*/true);
70 pWrtShell->EndPara(/*bSelect=*/true);
71 dispatchCommand(mxComponent, ".uno:ResetAttributes", {});
73 // the background color should revert to the color for 00Background style
74 CPPUNIT_ASSERT_EQUAL(Color(0xdedce6), getProperty<Color>(getParagraph(2), "FillColor"));
75 // the paragraph style should not be reset
76 CPPUNIT_ASSERT_EQUAL(OUString("00Background"),
77 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
78 CPPUNIT_ASSERT_EQUAL(OUString("00Background"),
79 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
81 // Save it and load it back.
82 saveAndReload("writer8");
84 CPPUNIT_ASSERT_EQUAL(Color(0xdedce6), getProperty<Color>(getParagraph(2), "FillColor"));
85 // on round-trip, the paragraph style name was lost
86 CPPUNIT_ASSERT_EQUAL(OUString("00Background"),
87 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
88 CPPUNIT_ASSERT_EQUAL(OUString("00Background"),
89 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
92 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdfChangeNumberingListAutoFormat)
94 createSwDoc("tdf117923.docx");
95 SwDoc* pDoc = getSwDoc();
97 // Ensure that all text portions are calculated before testing.
98 SwViewShell* pViewShell = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
99 CPPUNIT_ASSERT(pViewShell);
100 pViewShell->Reformat();
102 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
104 // Check that we actually test the line we need
105 assertXPathContent(pXmlDoc, "/root/page/body/tab/row/cell/txt[3]", "GHI GHI GHI GHI");
106 assertXPath(pXmlDoc,
107 "/root/page/body/tab/row/cell/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion",
108 "type", "PortionType::Number");
109 assertXPath(pXmlDoc,
110 "/root/page/body/tab/row/cell/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion",
111 "expand", "2.");
112 // The numbering height was 960 in DOC format.
113 assertXPath(
114 pXmlDoc,
115 "/root/page/body/tab/row/cell/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont",
116 "height", "220");
118 // tdf#127606: now it's possible to change formatting of numbering
119 // increase font size (220 -> 260)
120 dispatchCommand(mxComponent, ".uno:SelectAll", {});
121 dispatchCommand(mxComponent, ".uno:Grow", {});
122 pViewShell->Reformat();
123 discardDumpedLayout();
124 pXmlDoc = parseLayoutDump();
125 assertXPath(
126 pXmlDoc,
127 "/root/page/body/tab/row/cell/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont",
128 "height", "260");
130 // save it to DOCX
131 saveAndReload("Office Open XML Text");
132 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
133 pViewShell
134 = pTextDoc->GetDocShell()->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
135 pViewShell->Reformat();
136 discardDumpedLayout();
137 pXmlDoc = parseLayoutDump();
138 // this was 220
139 assertXPath(
140 pXmlDoc,
141 "/root/page/body/tab/row/cell/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion/SwFont",
142 "height", "260");
145 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf101534)
147 // Copy the first paragraph of the document.
148 createSwDoc("tdf101534.fodt");
149 SwDoc* pDoc = getSwDoc();
150 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
151 pWrtShell->EndPara(/*bSelect=*/true);
152 dispatchCommand(mxComponent, ".uno:Copy", {});
154 // Go to the second paragraph, assert that we have margins as direct
155 // formatting.
156 pWrtShell->Down(/*bSelect=*/false);
157 SfxItemSet aSet(pWrtShell->GetAttrPool(),
158 svl::Items<RES_MARGIN_FIRSTLINE, RES_MARGIN_TEXTLEFT>);
159 pWrtShell->GetCurAttr(aSet);
160 CPPUNIT_ASSERT(!aSet.HasItem(RES_MARGIN_FIRSTLINE));
161 CPPUNIT_ASSERT(aSet.HasItem(RES_MARGIN_TEXTLEFT));
162 CPPUNIT_ASSERT_EQUAL(::tools::Long(0), aSet.GetItem(RES_MARGIN_TEXTLEFT)->GetTextLeft());
164 // Make sure that direct formatting is preserved during paste.
165 pWrtShell->EndPara(/*bSelect=*/false);
166 dispatchCommand(mxComponent, ".uno:Paste", {});
167 aSet.ClearItem();
168 pWrtShell->GetCurAttr(aSet);
169 // This failed, direct formatting was lost.
170 CPPUNIT_ASSERT(!aSet.HasItem(RES_MARGIN_FIRSTLINE));
171 CPPUNIT_ASSERT(aSet.HasItem(RES_MARGIN_TEXTLEFT));
172 CPPUNIT_ASSERT_EQUAL(::tools::Long(0), aSet.GetItem(RES_MARGIN_TEXTLEFT)->GetTextLeft());
175 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testExtendedSelectAllHang)
177 createSwDoc();
178 SwDoc* const pDoc = getSwDoc();
179 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
181 pWrtShell->InsertFootnote("");
182 pWrtShell->StartOfSection();
183 SwView* pView = pDoc->GetDocShell()->GetView();
184 SfxStringItem aLangString(SID_LANGUAGE_STATUS, "Default_Spanish (Bolivia)");
185 // this looped
186 pView->GetViewFrame().GetDispatcher()->ExecuteList(SID_LANGUAGE_STATUS, SfxCallMode::SYNCHRON,
187 { &aLangString });
190 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineMoveInsertInDelete)
192 createSwDoc();
193 SwDoc* const pDoc = getSwDoc();
194 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
196 pWrtShell->Insert(" foo");
197 pWrtShell->SttEndDoc(true);
198 pWrtShell->InsertFootnote("");
199 CPPUNIT_ASSERT(pWrtShell->IsCursorInFootnote());
200 RedlineFlags const mode(pWrtShell->GetRedlineFlags() | RedlineFlags::On);
201 CPPUNIT_ASSERT(mode & (RedlineFlags::ShowDelete | RedlineFlags::ShowInsert));
202 pWrtShell->SetRedlineFlags(mode);
203 // insert redline
204 pWrtShell->Insert("bar");
205 // first delete redline, logically containing the insert redline
206 // (note: Word apparently allows similar things...)
207 pWrtShell->SttEndDoc(true);
208 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
209 pWrtShell->Delete(); // the footnote
210 // second delete redline, following the first one
211 pWrtShell->EndOfSection(false);
212 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 3, /*bBasicCall=*/false);
213 pWrtShell->Delete(); // "foo"
215 // hiding used to copy the 2nd delete redline "foo", but not delete it
216 pWrtShell->SetRedlineFlags(mode & ~RedlineFlags::ShowDelete); // hide
217 CPPUNIT_ASSERT_EQUAL(OUString(" "),
218 pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode()->GetText());
219 pWrtShell->SetRedlineFlags(mode); // show again
220 CPPUNIT_ASSERT_EQUAL(OUString(u"\u0001 foo"),
221 pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode()->GetText());
224 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineInHiddenSection)
226 createSwDoc();
227 SwDoc* const pDoc = getSwDoc();
228 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
230 pWrtShell->SplitNode();
231 pWrtShell->Insert("foo");
232 pWrtShell->SplitNode();
233 pWrtShell->Insert("bar");
234 pWrtShell->SplitNode();
235 pWrtShell->Insert("baz");
237 RedlineFlags const mode(pWrtShell->GetRedlineFlags() | RedlineFlags::On);
238 CPPUNIT_ASSERT(mode & (RedlineFlags::ShowDelete | RedlineFlags::ShowInsert));
239 pWrtShell->SetRedlineFlags(mode);
241 // delete paragraph "bar"
242 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
243 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 8, /*bBasicCall=*/false);
244 pWrtShell->Delete();
246 pWrtShell->StartOfSection();
247 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
248 pWrtShell->EndOfSection(true);
250 SwSectionData section(SectionType::Content, pWrtShell->GetUniqueSectionName());
251 section.SetHidden(true);
252 SwSection const* pSection = pWrtShell->InsertSection(section, nullptr);
254 SwSectionNode const* pNode = pSection->GetFormat()->GetSectionNode();
256 CPPUNIT_ASSERT(
257 !pNode->GetNodes()[pNode->GetIndex() + 1]->GetTextNode()->getLayoutFrame(nullptr));
258 CPPUNIT_ASSERT(
259 !pNode->GetNodes()[pNode->GetIndex() + 2]->GetTextNode()->getLayoutFrame(nullptr));
260 CPPUNIT_ASSERT(
261 !pNode->GetNodes()[pNode->GetIndex() + 3]->GetTextNode()->getLayoutFrame(nullptr));
262 CPPUNIT_ASSERT(pNode->GetNodes()[pNode->GetIndex() + 4]->IsEndNode());
264 pWrtShell->SetRedlineFlags(mode & ~RedlineFlags::ShowDelete); // hide
266 CPPUNIT_ASSERT(
267 !pNode->GetNodes()[pNode->GetIndex() + 1]->GetTextNode()->getLayoutFrame(nullptr));
268 CPPUNIT_ASSERT(pNode->GetNodes()[pNode->GetIndex() + 2]->IsEndNode());
270 pWrtShell->SetRedlineFlags(mode); // show again
272 CPPUNIT_ASSERT(
273 !pNode->GetNodes()[pNode->GetIndex() + 1]->GetTextNode()->getLayoutFrame(nullptr));
274 // there was a frame created here
275 CPPUNIT_ASSERT(
276 !pNode->GetNodes()[pNode->GetIndex() + 2]->GetTextNode()->getLayoutFrame(nullptr));
277 CPPUNIT_ASSERT(
278 !pNode->GetNodes()[pNode->GetIndex() + 3]->GetTextNode()->getLayoutFrame(nullptr));
279 CPPUNIT_ASSERT(pNode->GetNodes()[pNode->GetIndex() + 4]->IsEndNode());
282 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineSplitContentNode)
284 createSwDoc("try2.fodt");
285 SwDoc* pDoc = getSwDoc();
286 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
288 SwViewOption aViewOptions(*pWrtShell->GetViewOptions());
289 // these are required so that IsBlank() is true
290 aViewOptions.SetBlank(true);
291 aViewOptions.SetViewMetaChars(true);
292 pWrtShell->ApplyViewOptions(aViewOptions);
294 // enable redlining
295 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
296 // hide
297 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
299 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
300 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
301 CPPUNIT_ASSERT_MESSAGE(
302 "redlines should be visible",
303 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
305 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
307 pWrtShell->CalcLayout();
308 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 18, /*bBasicCall=*/false);
309 pWrtShell->SplitNode(true);
310 rUndoManager.Undo();
311 // crashed
312 pWrtShell->SplitNode(true);
313 rUndoManager.Undo();
314 rUndoManager.Redo();
315 rUndoManager.Undo();
316 rUndoManager.Redo();
317 rUndoManager.Undo();
318 pWrtShell->SplitNode(true);
319 rUndoManager.Undo();
322 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137318)
324 createSwDoc();
325 SwDoc* const pDoc = getSwDoc();
326 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
328 pWrtShell->Insert("A");
330 // enable redlining
331 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
332 // hide
333 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
335 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
336 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
337 CPPUNIT_ASSERT_MESSAGE(
338 "redlines should be visible",
339 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
340 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
342 pWrtShell->DelLine();
343 pWrtShell->StartOfSection(false);
344 pWrtShell->SplitNode(true);
345 pWrtShell->SplitNode(true);
347 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
349 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 3);
350 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion", 0);
351 assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion", 0);
352 // not sure why there's an empty text portion here, but it's not a problem
353 assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwParaPortion", 1);
354 assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwParaPortion",
355 "type", "PortionType::Para");
356 assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwParaPortion",
357 "portion", "");
359 pWrtShell->Undo();
361 // the problem was that here the "A" showed up again
362 discardDumpedLayout();
363 pXmlDoc = parseLayoutDump();
364 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 2);
365 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion", 0);
366 assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion", 1);
367 assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion",
368 "type", "PortionType::Para");
369 assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion",
370 "portion", "");
372 pWrtShell->Undo();
374 discardDumpedLayout();
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", "PortionType::Para");
380 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
381 "portion", "");
383 pWrtShell->Undo();
385 // now the "A" is no longer deleted
386 discardDumpedLayout();
387 pXmlDoc = parseLayoutDump();
388 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 1);
389 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion", 1);
390 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
391 "type", "PortionType::Para");
392 assertXPath(pXmlDoc,
393 "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[@portion]", 1);
394 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
395 "length", "1");
397 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
398 "portion", "A");
401 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf136704)
403 createSwDoc();
404 SwDoc* pDoc = getSwDoc();
405 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
406 SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect());
407 corr.GetSwFlags().bReplaceStyles = true;
408 SvxSwAutoFormatFlags flags(*SwEditShell::GetAutoFormatFlags());
409 comphelper::ScopeGuard const g([=]() { SwEditShell::SetAutoFormatFlags(&flags); });
410 flags.bReplaceStyles = true;
411 SwEditShell::SetAutoFormatFlags(&flags);
413 pWrtShell->Insert("test");
414 const sal_Unicode cIns = ':';
415 pWrtShell->AutoCorrect(corr, cIns);
417 SwXTextDocument* pXTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get());
418 CPPUNIT_ASSERT(pXTextDocument);
419 pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RETURN);
420 pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_RETURN);
421 Scheduler::ProcessEventsToIdle();
423 // Without the fix in place, this test would have crashed here
425 CPPUNIT_ASSERT_EQUAL(OUString("Heading 3"),
426 getProperty<OUString>(getParagraph(1), "ParaStyleName"));
429 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf134250)
431 createSwDoc("tdf134250.fodt");
433 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
434 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
435 uno::UNO_QUERY);
436 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
438 uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
439 uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(),
440 uno::UNO_QUERY);
442 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
444 uno::Reference<text::XTextContent> xTextContent(xSections->getByIndex(0), uno::UNO_QUERY);
445 CPPUNIT_ASSERT_EQUAL(OUString("foo" SAL_NEWLINE_STRING "bar"),
446 xTextContent->getAnchor()->getString());
448 // select all with table at start -> 3 times
449 dispatchCommand(mxComponent, ".uno:SelectAll", {});
450 dispatchCommand(mxComponent, ".uno:SelectAll", {});
451 dispatchCommand(mxComponent, ".uno:SelectAll", {});
453 dispatchCommand(mxComponent, ".uno:Copy", {});
455 dispatchCommand(mxComponent, ".uno:Paste", {});
457 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
458 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
460 // this would crash in 2 different ways
461 dispatchCommand(mxComponent, ".uno:Undo", {});
463 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
464 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
466 // Without the fix in place, section's content would have been gone after undo
467 CPPUNIT_ASSERT_EQUAL(OUString("foo" SAL_NEWLINE_STRING "bar"),
468 xTextContent->getAnchor()->getString());
470 dispatchCommand(mxComponent, ".uno:Redo", {});
472 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
473 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
475 dispatchCommand(mxComponent, ".uno:Undo", {});
477 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
478 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
479 CPPUNIT_ASSERT_EQUAL(OUString("foo" SAL_NEWLINE_STRING "bar"),
480 xTextContent->getAnchor()->getString());
482 dispatchCommand(mxComponent, ".uno:Redo", {});
484 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
485 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
488 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf134436)
490 createSwDoc("tdf134436.fodt");
491 SwDoc* pDoc = getSwDoc();
493 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
494 CPPUNIT_ASSERT(pWrtShell);
496 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
497 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
498 uno::UNO_QUERY);
499 uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
500 uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(),
501 uno::UNO_QUERY);
503 // select all 3 times, table at the start
504 dispatchCommand(mxComponent, ".uno:SelectAll", {});
505 dispatchCommand(mxComponent, ".uno:SelectAll", {});
506 dispatchCommand(mxComponent, ".uno:SelectAll", {});
508 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
509 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
510 // the stupid SwXTextView::getString doesn't work "for symmetry" so use CursorShell
511 CPPUNIT_ASSERT_EQUAL(OUString("a\nb\n"), pWrtShell->GetCursor()->GetText());
513 // first, the section doesn't get deleted
514 dispatchCommand(mxComponent, ".uno:Delete", {});
516 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
517 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
518 CPPUNIT_ASSERT_EQUAL(OUString(""), pWrtShell->GetCursor()->GetText());
520 dispatchCommand(mxComponent, ".uno:Undo", {});
522 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
523 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
524 CPPUNIT_ASSERT_EQUAL(OUString("a\nb\n"), pWrtShell->GetCursor()->GetText());
526 // second, the section does get deleted because point is at the end
527 dispatchCommand(mxComponent, ".uno:Delete", {});
529 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
530 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xSections->getCount());
531 CPPUNIT_ASSERT_EQUAL(OUString(""), pWrtShell->GetCursor()->GetText());
533 dispatchCommand(mxComponent, ".uno:Undo", {});
535 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
536 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
537 CPPUNIT_ASSERT_EQUAL(OUString("a\nb\n"), pWrtShell->GetCursor()->GetText());
539 // the problem was that the section was not deleted on Redo
540 dispatchCommand(mxComponent, ".uno:Redo", {});
542 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
543 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xSections->getCount());
544 CPPUNIT_ASSERT_EQUAL(OUString(""), pWrtShell->GetCursor()->GetText());
546 dispatchCommand(mxComponent, ".uno:Undo", {});
548 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
549 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
550 CPPUNIT_ASSERT_EQUAL(OUString("a\nb\n"), pWrtShell->GetCursor()->GetText());
552 dispatchCommand(mxComponent, ".uno:Redo", {});
554 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
555 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xSections->getCount());
556 CPPUNIT_ASSERT_EQUAL(OUString(""), pWrtShell->GetCursor()->GetText());
559 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf134252)
561 createSwDoc("tdf134252.fodt");
563 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
564 uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
565 xModel->getCurrentController(), uno::UNO_QUERY);
566 uno::Reference<text::XTextRange> xCursor(xTextViewCursorSupplier->getViewCursor());
567 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
568 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
569 uno::UNO_QUERY);
570 uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
571 uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(),
572 uno::UNO_QUERY);
574 // select all with section
575 dispatchCommand(mxComponent, ".uno:SelectAll", {});
577 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
578 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
579 CPPUNIT_ASSERT_EQUAL(OUString("bar" SAL_NEWLINE_STRING "baz" SAL_NEWLINE_STRING),
580 xCursor->getString());
582 dispatchCommand(mxComponent, ".uno:Delete", {});
584 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
585 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
586 CPPUNIT_ASSERT_EQUAL(OUString(""), xCursor->getString());
588 // this would crash
589 dispatchCommand(mxComponent, ".uno:Undo", {});
591 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
592 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
593 CPPUNIT_ASSERT_EQUAL(OUString("bar" SAL_NEWLINE_STRING "baz" SAL_NEWLINE_STRING),
594 xCursor->getString());
596 dispatchCommand(mxComponent, ".uno:Redo", {});
598 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
599 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
600 CPPUNIT_ASSERT_EQUAL(OUString(""), xCursor->getString());
602 dispatchCommand(mxComponent, ".uno:Undo", {});
604 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
605 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
606 CPPUNIT_ASSERT_EQUAL(OUString("bar" SAL_NEWLINE_STRING "baz" SAL_NEWLINE_STRING),
607 xCursor->getString());
609 dispatchCommand(mxComponent, ".uno:Redo", {});
611 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
612 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
613 CPPUNIT_ASSERT_EQUAL(OUString(""), xCursor->getString());
616 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf136452)
618 createSwDoc("tdf136452.fodt");
619 SwDoc* pDoc = getSwDoc();
621 SwNodeOffset const nNodes(pDoc->GetNodes().Count());
623 SwWrtShell* const pWrtShell(pDoc->GetDocShell()->GetWrtShell());
625 // first deletion spanning 2 sections
626 pWrtShell->SttEndDoc(false);
627 pWrtShell->SetMark();
628 pWrtShell->Up(true, 2);
629 pWrtShell->Delete();
631 // 2 paragraphs deleted, last section is gone
632 CPPUNIT_ASSERT_EQUAL(nNodes - 4, pDoc->GetNodes().Count());
634 // second deletion spanning 2 sections
635 pWrtShell->SetMark();
636 pWrtShell->Up(true, 3);
637 pWrtShell->Delete();
639 // 3 paragraphs deleted, 2nd section is gone
640 CPPUNIT_ASSERT_EQUAL(nNodes - 9, pDoc->GetNodes().Count());
642 pWrtShell->Undo();
644 // 2 paragraphs deleted, last section is gone
645 CPPUNIT_ASSERT_EQUAL(nNodes - 4, pDoc->GetNodes().Count());
647 // this crashed
648 pWrtShell->Undo();
650 CPPUNIT_ASSERT_EQUAL(nNodes, pDoc->GetNodes().Count());
652 pWrtShell->Redo();
654 // 2 paragraphs deleted, last section is gone
655 CPPUNIT_ASSERT_EQUAL(nNodes - 4, pDoc->GetNodes().Count());
657 pWrtShell->Redo();
659 // 3 paragraphs deleted, 2nd section is gone
660 CPPUNIT_ASSERT_EQUAL(nNodes - 9, pDoc->GetNodes().Count());
663 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf136453)
665 createSwDoc("tdf136453.fodt");
666 SwDoc* pDoc = getSwDoc();
667 SwWrtShell* const pWrtShell(pDoc->GetDocShell()->GetWrtShell());
669 SwNodeOffset const nNodes(pDoc->GetNodes().Count());
671 pWrtShell->SttEndDoc(false);
672 pWrtShell->SetMark();
673 pWrtShell->Up(true, 1);
674 pWrtShell->SttPara(true);
675 pWrtShell->Delete();
677 // one paragraph deleted, section is gone
678 CPPUNIT_ASSERT_EQUAL(nNodes - 3, pDoc->GetNodes().Count());
680 pWrtShell->Undo();
682 CPPUNIT_ASSERT_EQUAL(nNodes, pDoc->GetNodes().Count());
684 // check that every node has 1 frame
685 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
686 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 3);
687 assertXPath(pXmlDoc, "/root/page[1]/body/section", 1);
688 assertXPath(pXmlDoc, "/root/page[1]/body/section/txt", 1);
690 pWrtShell->Redo();
692 // one paragraph deleted, section is gone
693 CPPUNIT_ASSERT_EQUAL(nNodes - 3, pDoc->GetNodes().Count());
695 discardDumpedLayout();
696 pXmlDoc = parseLayoutDump();
697 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 3);
698 assertXPath(pXmlDoc, "/root/page[1]/body/section", 0);
700 pWrtShell->Undo();
702 CPPUNIT_ASSERT_EQUAL(nNodes, pDoc->GetNodes().Count());
704 discardDumpedLayout();
705 pXmlDoc = parseLayoutDump();
706 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 3);
707 assertXPath(pXmlDoc, "/root/page[1]/body/section", 1);
708 assertXPath(pXmlDoc, "/root/page[1]/body/section/txt", 1);
711 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137245)
713 createSwDoc();
714 SwDoc* pDoc = getSwDoc();
715 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
716 SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect());
717 corr.GetSwFlags().bSetBorder = true;
718 // sigh, it's a global... err i mean Singleton design pattern *eyeroll*
719 SvxSwAutoFormatFlags flags(*SwEditShell::GetAutoFormatFlags());
720 comphelper::ScopeGuard const g([=]() { SwEditShell::SetAutoFormatFlags(&flags); });
721 flags.bSetBorder = true;
722 SwEditShell::SetAutoFormatFlags(&flags);
725 SwFormatAnchor anchor(RndStdIds::FLY_AT_PARA);
726 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
727 SfxItemSet flySet(pDoc->GetAttrPool(),
728 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
729 flySet.Put(anchor);
730 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
731 flySet.Put(size); // set a size, else we get 1 char per line...
732 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
733 CPPUNIT_ASSERT(pFly != nullptr);
736 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
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);
746 // move cursor back to body
747 pWrtShell->SttEndDoc(false);
748 // keep first paragraph empty so that its flys may be deleted too
749 //pWrtShell->Insert("abc");
750 pWrtShell->SplitNode(false);
753 SwFormatAnchor anchor(RndStdIds::FLY_AT_PARA);
754 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
755 SfxItemSet flySet(pDoc->GetAttrPool(),
756 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
757 flySet.Put(anchor);
758 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
759 flySet.Put(size); // set a size, else we get 1 char per line...
760 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
761 CPPUNIT_ASSERT(pFly != nullptr);
764 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
765 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
766 SfxItemSet flySet(pDoc->GetAttrPool(),
767 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
768 flySet.Put(anchor);
769 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
770 flySet.Put(size); // set a size, else we get 1 char per line...
771 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
772 CPPUNIT_ASSERT(pFly != nullptr);
775 const auto& rFormats = *pDoc->GetSpzFrameFormats();
776 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rFormats.size());
778 // move cursor back to body
779 pWrtShell->SttEndDoc(false);
780 pWrtShell->Insert("---");
781 pWrtShell->SplitNode(true);
783 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rFormats.size());
785 // check that the AutoFormat did something
786 pWrtShell->SttEndDoc(true);
787 SfxItemSet set{ pDoc->GetAttrPool(), svl::Items<RES_BOX, RES_BOX> };
788 pWrtShell->GetCurParAttr(set);
789 CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, set.GetItemState(RES_BOX, false));
792 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf132236)
794 createSwDoc("tdf132236.odt");
795 SwDoc* pDoc = getSwDoc();
797 // select everything and delete
798 SwWrtShell* const pWrtShell(pDoc->GetDocShell()->GetWrtShell());
799 pWrtShell->Down(true);
800 pWrtShell->Down(true);
801 pWrtShell->Down(true);
802 pWrtShell->Delete();
803 sw::UndoManager& rUndoManager(pDoc->GetUndoManager());
804 rUndoManager.Undo();
806 // check that the text frames exist inside their sections
807 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
808 assertXPath(pXmlDoc, "/root/page[1]/body/section[1]/txt", 1);
809 assertXPath(pXmlDoc, "/root/page[1]/body/section[2]/txt", 2);
810 assertXPath(pXmlDoc, "/root/page[1]/body/txt", 1);
813 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf131912)
815 createSwDoc();
816 SwDoc* const pDoc = getSwDoc();
817 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
819 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
821 sw::UnoCursorPointer pCursor(
822 pDoc->CreateUnoCursor(SwPosition(pDoc->GetNodes().GetEndOfContent(), SwNodeOffset(-1))));
824 pDoc->getIDocumentContentOperations().InsertString(*pCursor, "foo");
827 SfxItemSet flySet(pDoc->GetAttrPool(),
828 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
829 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
830 pWrtShell->StartOfSection(false);
831 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
832 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
833 flySet.Put(anchor);
834 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
835 flySet.Put(size); // set a size, else we get 1 char per line...
836 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
837 CPPUNIT_ASSERT(pFly != nullptr);
839 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
841 pCursor->SetMark();
842 pCursor->GetMark()->nContent.Assign(pCursor->GetPointContentNode(), 0);
843 pCursor->GetPoint()->nContent.Assign(pCursor->GetPointContentNode(), 3);
845 // replace with more text
846 pDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, "blahblah", false);
848 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
849 CPPUNIT_ASSERT_EQUAL(OUString("blahblah"), pCursor->GetPointNode().GetTextNode()->GetText());
851 rUndoManager.Undo();
853 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
854 CPPUNIT_ASSERT_EQUAL(OUString("foo"), pCursor->GetPointNode().GetTextNode()->GetText());
856 rUndoManager.Redo();
858 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
859 CPPUNIT_ASSERT_EQUAL(OUString("blahblah"), pCursor->GetPointNode().GetTextNode()->GetText());
861 rUndoManager.Undo();
863 pCursor->GetMark()->nContent.Assign(pCursor->GetPointContentNode(), 0);
864 pCursor->GetPoint()->nContent.Assign(pCursor->GetPointContentNode(), 3);
866 // replace with less text
867 pDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, "x", false);
869 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
870 CPPUNIT_ASSERT_EQUAL(OUString("x"), pCursor->GetPointNode().GetTextNode()->GetText());
872 rUndoManager.Undo();
874 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
875 CPPUNIT_ASSERT_EQUAL(OUString("foo"), pCursor->GetPointNode().GetTextNode()->GetText());
877 rUndoManager.Redo();
879 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
880 CPPUNIT_ASSERT_EQUAL(OUString("x"), pCursor->GetPointNode().GetTextNode()->GetText());
882 rUndoManager.Undo();
884 pCursor->GetMark()->nContent.Assign(pCursor->GetPointContentNode(), 0);
885 pCursor->GetPoint()->nContent.Assign(pCursor->GetPointContentNode(), 3);
887 // regex replace with paragraph breaks
888 pDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, "xyz\\n\\nquux\\n", true);
890 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
891 pWrtShell->StartOfSection(false);
892 CPPUNIT_ASSERT_EQUAL(OUString("xyz"),
893 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
894 pWrtShell->EndOfSection(true);
895 CPPUNIT_ASSERT_EQUAL(OUString("xyz\n\nquux\n"), pWrtShell->GetCursor()->GetText());
897 rUndoManager.Undo();
899 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
900 CPPUNIT_ASSERT_EQUAL(OUString("foo"), pCursor->GetPointNode().GetTextNode()->GetText());
901 pWrtShell->StartOfSection(false);
902 pWrtShell->EndOfSection(true);
903 CPPUNIT_ASSERT_EQUAL(OUString("foo"), pWrtShell->GetCursor()->GetText());
905 rUndoManager.Redo();
907 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
908 pWrtShell->StartOfSection(false);
909 CPPUNIT_ASSERT_EQUAL(OUString("xyz"),
910 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
911 pWrtShell->EndOfSection(true);
912 CPPUNIT_ASSERT_EQUAL(OUString("xyz\n\nquux\n"), pWrtShell->GetCursor()->GetText());
914 // regex replace with paragraph join
915 pWrtShell->StartOfSection(false);
916 pWrtShell->Down(true);
917 pDoc->getIDocumentContentOperations().ReplaceRange(*pWrtShell->GetCursor(), "bar", true);
919 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
920 pWrtShell->StartOfSection(false);
921 CPPUNIT_ASSERT_EQUAL(OUString("bar"),
922 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
923 pWrtShell->EndOfSection(true);
924 CPPUNIT_ASSERT_EQUAL(OUString("bar\nquux\n"), pWrtShell->GetCursor()->GetText());
926 rUndoManager.Undo();
928 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
929 pWrtShell->StartOfSection(false);
930 CPPUNIT_ASSERT_EQUAL(OUString("xyz"),
931 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
932 pWrtShell->EndOfSection(true);
933 CPPUNIT_ASSERT_EQUAL(OUString("xyz\n\nquux\n"), pWrtShell->GetCursor()->GetText());
935 rUndoManager.Redo();
937 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
938 pWrtShell->StartOfSection(false);
939 CPPUNIT_ASSERT_EQUAL(OUString("bar"),
940 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
941 pWrtShell->EndOfSection(true);
942 CPPUNIT_ASSERT_EQUAL(OUString("bar\nquux\n"), pWrtShell->GetCursor()->GetText());
944 rUndoManager.Undo();
946 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
947 pWrtShell->StartOfSection(false);
948 CPPUNIT_ASSERT_EQUAL(OUString("xyz"),
949 pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText());
950 pWrtShell->EndOfSection(true);
951 CPPUNIT_ASSERT_EQUAL(OUString("xyz\n\nquux\n"), pWrtShell->GetCursor()->GetText());
953 rUndoManager.Undo();
955 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
956 CPPUNIT_ASSERT_EQUAL(OUString("foo"), pCursor->GetPointNode().GetTextNode()->GetText());
957 pWrtShell->StartOfSection(false);
958 pWrtShell->EndOfSection(true);
959 CPPUNIT_ASSERT_EQUAL(OUString("foo"), pWrtShell->GetCursor()->GetText());
962 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf140007)
964 createSwDoc();
965 SwDoc* const pDoc = getSwDoc();
966 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
968 pWrtShell->Insert("foo");
969 pWrtShell->SplitNode();
970 pWrtShell->Insert("bar");
971 pWrtShell->SplitNode();
972 pWrtShell->Insert("baz");
973 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(13), pDoc->GetNodes().Count());
974 CPPUNIT_ASSERT_EQUAL(OUString("foo"),
975 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
976 CPPUNIT_ASSERT_EQUAL(OUString("bar"),
977 pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
978 CPPUNIT_ASSERT_EQUAL(OUString("baz"),
979 pDoc->GetNodes()[SwNodeOffset(11)]->GetTextNode()->GetText());
981 pWrtShell->SttEndDoc(true);
982 pWrtShell->EndPara(false);
983 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
984 pWrtShell->Replace(" ", true);
985 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(12), pDoc->GetNodes().Count());
986 CPPUNIT_ASSERT_EQUAL(OUString("foo bar"),
987 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
988 CPPUNIT_ASSERT_EQUAL(OUString("baz"),
989 pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
991 pWrtShell->SttEndDoc(true);
992 pWrtShell->EndPara(false);
993 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
994 pWrtShell->Replace(" ", true);
995 CPPUNIT_ASSERT_EQUAL(OUString("foo bar baz"),
996 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
997 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(11), pDoc->GetNodes().Count());
999 pWrtShell->Undo();
1001 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(12), pDoc->GetNodes().Count());
1002 CPPUNIT_ASSERT_EQUAL(OUString("foo bar"),
1003 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
1004 CPPUNIT_ASSERT_EQUAL(OUString("baz"),
1005 pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
1007 pWrtShell->Undo();
1009 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(13), pDoc->GetNodes().Count());
1010 CPPUNIT_ASSERT_EQUAL(OUString("foo"),
1011 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
1012 CPPUNIT_ASSERT_EQUAL(OUString("bar"),
1013 pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
1014 CPPUNIT_ASSERT_EQUAL(OUString("baz"),
1015 pDoc->GetNodes()[SwNodeOffset(11)]->GetTextNode()->GetText());
1017 pWrtShell->Redo();
1019 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(12), pDoc->GetNodes().Count());
1020 CPPUNIT_ASSERT_EQUAL(OUString("foo bar"),
1021 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
1022 CPPUNIT_ASSERT_EQUAL(OUString("baz"),
1023 pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
1025 pWrtShell->Redo();
1027 CPPUNIT_ASSERT_EQUAL(OUString("foo bar baz"),
1028 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
1029 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(11), pDoc->GetNodes().Count());
1031 pWrtShell->Undo();
1033 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(12), pDoc->GetNodes().Count());
1034 CPPUNIT_ASSERT_EQUAL(OUString("foo bar"),
1035 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
1036 CPPUNIT_ASSERT_EQUAL(OUString("baz"),
1037 pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
1039 pWrtShell->Undo();
1041 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(13), pDoc->GetNodes().Count());
1042 CPPUNIT_ASSERT_EQUAL(OUString("foo"),
1043 pDoc->GetNodes()[SwNodeOffset(9)]->GetTextNode()->GetText());
1044 CPPUNIT_ASSERT_EQUAL(OUString("bar"),
1045 pDoc->GetNodes()[SwNodeOffset(10)]->GetTextNode()->GetText());
1046 CPPUNIT_ASSERT_EQUAL(OUString("baz"),
1047 pDoc->GetNodes()[SwNodeOffset(11)]->GetTextNode()->GetText());
1050 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf139982)
1052 createSwDoc();
1053 SwDoc* const pDoc = getSwDoc();
1054 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1056 // turn on redlining and show changes
1057 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1058 | RedlineFlags::ShowInsert);
1059 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1060 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1061 CPPUNIT_ASSERT_MESSAGE(
1062 "redlines should be visible",
1063 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1065 pWrtShell->Insert("helloo");
1067 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1069 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
1070 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
1071 SfxItemSet flySet(pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>);
1072 flySet.Put(anchor);
1073 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
1074 CPPUNIT_ASSERT(pFly != nullptr);
1077 pWrtShell->SttEndDoc(true);
1078 pWrtShell->EndPara(/*bSelect=*/true);
1080 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1082 pWrtShell->Replace("hello", true);
1084 // the problem was that a redline delete with the same author as redline
1085 // insert has its text deleted immediately, including anchored flys.
1086 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1088 pWrtShell->Undo();
1090 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1092 pWrtShell->Redo();
1094 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1096 pWrtShell->Undo();
1098 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1101 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf135976)
1103 createSwDoc();
1104 SwDoc* const pDoc = getSwDoc();
1105 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1107 pWrtShell->Insert("foobar");
1109 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
1110 SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
1111 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
1112 SfxItemSet flySet(pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>);
1113 flySet.Put(anchor);
1114 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
1115 CPPUNIT_ASSERT(pFly != nullptr);
1117 // turn on redlining and show changes
1118 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1119 | RedlineFlags::ShowInsert);
1120 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
1121 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1122 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1123 CPPUNIT_ASSERT_MESSAGE(
1124 "redlines should be visible",
1125 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1126 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
1128 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1129 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1130 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pFly->GetAnchor().GetAnchorContentOffset());
1132 pWrtShell->UnSelectFrame();
1133 pWrtShell->SttEndDoc(/*bStart=*/false);
1134 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1136 pWrtShell->DelLeft();
1137 pWrtShell->DelLeft();
1139 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1140 // the problem was that the fly was deleted from the layout
1141 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1142 // check that the anchor was moved outside the redline
1143 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pFly->GetAnchor().GetAnchorContentOffset());
1145 pWrtShell->Undo(2);
1147 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1148 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1149 // check that the anchor was restored
1150 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pFly->GetAnchor().GetAnchorContentOffset());
1152 pWrtShell->Redo(2);
1154 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1155 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1156 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pFly->GetAnchor().GetAnchorContentOffset());
1158 pWrtShell->Undo(2);
1160 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1161 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1162 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pFly->GetAnchor().GetAnchorContentOffset());
1164 // now again in the other direction:
1166 pWrtShell->SttEndDoc(/*bStart=*/false);
1167 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 3, /*bBasicCall=*/false);
1169 pWrtShell->DelRight();
1170 pWrtShell->DelRight();
1172 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1173 // the problem was that the fly was deleted from the layout
1174 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1175 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pFly->GetAnchor().GetAnchorContentOffset());
1177 pWrtShell->Undo(2);
1179 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1180 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1181 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pFly->GetAnchor().GetAnchorContentOffset());
1183 pWrtShell->Redo(2);
1185 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1186 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1187 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pFly->GetAnchor().GetAnchorContentOffset());
1189 pWrtShell->Undo(2);
1191 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1192 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLastPage()->GetSortedObjs()->size());
1193 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pFly->GetAnchor().GetAnchorContentOffset());
1196 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf39721)
1198 // FIXME: disabled on Windows because of a not reproducible problem (not related to the patch)
1199 #if !defined(_WIN32)
1200 // check move down with redlining
1201 createSwDoc("tdf39721.fodt");
1202 SwDoc* pDoc = getSwDoc();
1203 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
1205 //turn on red-lining and show changes
1206 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1207 | RedlineFlags::ShowInsert);
1208 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1209 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1210 CPPUNIT_ASSERT_MESSAGE(
1211 "redlines should be visible",
1212 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1214 // store original text of the document for checking Undo
1215 OUString sOrigText(pTextDoc->getText()->getString());
1217 // first paragraph is "Lorem ipsum" with deleted "m ips"
1218 CPPUNIT_ASSERT_EQUAL(OUString("Lorem ipsum"), getParagraph(1)->getString());
1220 // move down first paragraph with change tracking
1221 dispatchCommand(mxComponent, ".uno:MoveDown", {});
1223 // deletion isn't rejected
1224 CPPUNIT_ASSERT_EQUAL(OUString("Loremm"), getParagraph(3)->getString());
1226 // Undo and repeat it with the second paragraph
1227 dispatchCommand(mxComponent, ".uno:Undo", {});
1229 CPPUNIT_ASSERT_EQUAL(sOrigText, pTextDoc->getText()->getString());
1231 // second paragraph is "dolor sit" with deleted "lor "
1232 CPPUNIT_ASSERT_EQUAL(OUString("dolor sit"), getParagraph(2)->getString());
1234 // move down second paragraph with change tracking
1235 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1237 pWrtShell->Up(/*bSelect=*/false);
1238 pWrtShell->Down(/*bSelect=*/false);
1240 dispatchCommand(mxComponent, ".uno:MoveDown", {});
1242 // This was "dolor sit" (rejecting tracked deletion)
1243 CPPUNIT_ASSERT_EQUAL(OUString("dolsit"), getParagraph(4)->getString());
1245 dispatchCommand(mxComponent, ".uno:Undo", {});
1247 CPPUNIT_ASSERT_EQUAL(sOrigText, pTextDoc->getText()->getString());
1248 #endif
1251 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf145066_bad_paragraph_deletion)
1253 // check move down with redlining: jumping over a deleted paragraph
1254 // resulted bad deletion of the not deleted adjacent paragraph in Show Changes mode
1255 createSwDoc("tdf39721.fodt");
1256 SwDoc* pDoc = getSwDoc();
1258 //turn on red-lining and show changes
1259 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1260 | RedlineFlags::ShowInsert);
1261 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1262 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1263 CPPUNIT_ASSERT_MESSAGE(
1264 "redlines should be visible",
1265 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1267 // Three paragraphs (list items)
1268 CPPUNIT_ASSERT_EQUAL(3, getParagraphs());
1270 // move down once and move up two times second paragraph with change tracking
1271 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1272 pWrtShell->Down(/*bSelect=*/false);
1273 dispatchCommand(mxComponent, ".uno:MoveDown", {});
1274 dispatchCommand(mxComponent, ".uno:MoveUp", {});
1275 dispatchCommand(mxComponent, ".uno:MoveUp", {});
1277 // accept all changes
1278 dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {});
1280 // This was 2 (bad deletion of the first paragraph)
1281 // TODO fix unnecessary insertion of a new list item at the end of the document
1282 CPPUNIT_ASSERT(getParagraphs() >= 3);
1284 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
1285 // This was "Loremdolsit\namet.\n" (bad deletion of "m\n" at the end of item 1)
1286 CPPUNIT_ASSERT_EQUAL(OUString("Loremm" SAL_NEWLINE_STRING "dolsit" SAL_NEWLINE_STRING
1287 "amet." SAL_NEWLINE_STRING),
1288 pTextDoc->getText()->getString());
1291 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf145311_move_over_empty_paragraphs)
1293 // check move up/down with redlining: jumping over an empty paragraph
1294 // resulted bad insertion of the empty paragraph in Show Changes mode
1295 createSwDoc("tdf145311.fodt");
1296 SwDoc* pDoc = getSwDoc();
1298 //turn on red-lining and show changes
1299 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1300 | RedlineFlags::ShowInsert);
1301 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1302 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1303 CPPUNIT_ASSERT_MESSAGE(
1304 "redlines should be visible",
1305 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1307 // 8 paragraphs (list items)
1308 CPPUNIT_ASSERT_EQUAL(8, getParagraphs());
1310 // move down the first item over the empty paragraph
1311 for (int i = 0; i < 4; ++i)
1312 dispatchCommand(mxComponent, ".uno:MoveDown", {});
1314 SwEditShell* const pEditShell(pDoc->GetEditShell());
1315 // This was 3 (bad conversion of the empty item to a tracked insertion)
1316 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount());
1318 // check move up
1320 for (int i = 0; i < 3; ++i)
1321 dispatchCommand(mxComponent, ".uno:MoveUp", {});
1323 // This was 3 (bad conversion of the empty item to a tracked insertion)
1324 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount());
1327 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf54819)
1329 createSwDoc("tdf54819.fodt");
1330 SwDoc* pDoc = getSwDoc();
1332 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
1333 getProperty<OUString>(getParagraph(1), "ParaStyleName"));
1334 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1335 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1337 //turn on red-lining and hide changes
1338 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On);
1339 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1340 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1341 CPPUNIT_ASSERT_MESSAGE("redlines shouldn't be visible",
1342 !IDocumentRedlineAccess::IsShowChanges(
1343 pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1345 // remove first paragraph with paragraph break
1346 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1347 pWrtShell->EndPara(/*bSelect=*/true);
1348 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1349 dispatchCommand(mxComponent, ".uno:Cut", {});
1351 // remaining paragraph keeps its original style
1352 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1353 getProperty<OUString>(getParagraph(1), "ParaStyleName"));
1356 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf54819_keep_numbering_with_Undo)
1358 createSwDoc("tdf54819b.odt");
1359 SwDoc* pDoc = getSwDoc();
1361 // heading
1362 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
1363 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1364 CPPUNIT_ASSERT_EQUAL(OUString("Outline"),
1365 getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
1367 // next paragraph: bulleted list item
1369 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1370 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
1371 OUString sNumName = getProperty<OUString>(getParagraph(3), "NumberingStyleName");
1372 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1373 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1375 //turn on red-lining and show changes
1376 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1377 | RedlineFlags::ShowInsert);
1378 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On);
1379 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1380 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1381 CPPUNIT_ASSERT_MESSAGE("redlines shouldn't be visible",
1382 !IDocumentRedlineAccess::IsShowChanges(
1383 pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1385 // remove heading with paragraph break
1386 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1388 pWrtShell->Down(/*bSelect=*/false);
1389 pWrtShell->Down(/*bSelect=*/false);
1390 pWrtShell->Down(/*bSelect=*/false);
1391 pWrtShell->Down(/*bSelect=*/false);
1392 pWrtShell->Down(/*bSelect=*/false);
1393 pWrtShell->EndPara(/*bSelect=*/true);
1394 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1395 dispatchCommand(mxComponent, ".uno:Cut", {});
1397 // solved problem: changing paragraph style after deletion
1398 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1399 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1401 sNumName = getProperty<OUString>(getParagraph(2), "NumberingStyleName");
1402 // solved problem: lost numbering
1403 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1404 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1406 // accept deletion, remaining (now second) paragraph: still bulleted list item
1407 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
1408 rIDRA.AcceptAllRedline(true);
1410 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1411 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1412 sNumName = getProperty<OUString>(getParagraph(2), "NumberingStyleName");
1413 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1414 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1416 // solved problem: Undo with the workaround
1417 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1418 rUndoManager.Undo();
1419 rUndoManager.Undo();
1421 // heading, manual test is correct
1422 // TODO: it works well, but the test fails...
1423 // SwWrtShell* const pWrtShell2 = pDoc->GetDocShell()->GetWrtShell();
1424 // CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
1425 // getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1426 // CPPUNIT_ASSERT_EQUAL(OUString("Outline"),
1427 // getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
1429 // next paragraph: bulleted list item
1431 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1432 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
1433 sNumName = getProperty<OUString>(getParagraph(3), "NumberingStyleName");
1434 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1435 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1438 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119571_keep_numbering_with_Undo)
1440 // as the previous test, but with partial paragraph deletion:
1441 // all deleted paragraphs get the formatting of the first (the partially deleted) one
1442 createSwDoc("tdf54819b.odt");
1443 SwDoc* pDoc = getSwDoc();
1445 // heading
1446 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
1447 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1448 CPPUNIT_ASSERT_EQUAL(OUString("Outline"),
1449 getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
1451 // next paragraph: bulleted list item
1453 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1454 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
1455 OUString sNumName = getProperty<OUString>(getParagraph(3), "NumberingStyleName");
1456 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1457 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1459 // third paragraph: normal text without numbering
1461 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1462 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
1463 sNumName = getProperty<OUString>(getParagraph(4), "NumberingStyleName");
1464 CPPUNIT_ASSERT_MESSAGE("Bad numbering", sNumName.isEmpty());
1466 //turn on red-lining and show changes
1467 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1468 | RedlineFlags::ShowInsert);
1469 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On);
1470 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1471 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1472 CPPUNIT_ASSERT_MESSAGE("redlines shouldn't be visible",
1473 !IDocumentRedlineAccess::IsShowChanges(
1474 pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1476 // remove only end part of the heading and the next numbered paragraph with paragraph break
1477 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1479 pWrtShell->Down(/*bSelect=*/false);
1480 pWrtShell->Down(/*bSelect=*/false);
1481 pWrtShell->Down(/*bSelect=*/false);
1482 pWrtShell->Down(/*bSelect=*/false);
1483 pWrtShell->Down(/*bSelect=*/false);
1484 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 6, /*bBasicCall=*/false);
1485 pWrtShell->EndPara(/*bSelect=*/true);
1486 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 2, /*bBasicCall=*/false);
1487 pWrtShell->EndPara(/*bSelect=*/true);
1488 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1489 dispatchCommand(mxComponent, ".uno:Cut", {});
1491 // solved problem: changing paragraph style after deletion
1492 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
1493 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1495 // solved problem: apply numbering
1496 CPPUNIT_ASSERT_EQUAL(OUString("Outline"),
1497 getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
1499 // accept deletion
1500 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
1501 rIDRA.AcceptAllRedline(true);
1503 // Joined paragraph 2 and paragraph 4: Fusce...nunc.
1504 CPPUNIT_ASSERT(getParagraph(2)->getString().startsWith("Fusce"));
1505 CPPUNIT_ASSERT(getParagraph(2)->getString().endsWith("nunc."));
1506 // Remaining (now second) paragraph: it is still heading
1507 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
1508 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1509 CPPUNIT_ASSERT_EQUAL(OUString("Outline"),
1510 getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
1512 // solved problem: Undo with the workaround
1513 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1514 rUndoManager.Undo();
1515 rUndoManager.Undo();
1517 // heading
1519 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
1520 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1521 CPPUNIT_ASSERT_EQUAL(OUString("Outline"),
1522 getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
1524 // next paragraph: bulleted list item
1526 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1527 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
1528 sNumName = getProperty<OUString>(getParagraph(3), "NumberingStyleName");
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(OUString("Standard"),
1535 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
1536 sNumName = getProperty<OUString>(getParagraph(4), "NumberingStyleName");
1537 CPPUNIT_ASSERT_MESSAGE("Bad numbering", sNumName.isEmpty());
1540 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119571_keep_numbering_with_Reject)
1542 // as the previous test, but with partial paragraph deletion:
1543 // all deleted paragraphs get the formatting of the first (the partially deleted) one
1544 createSwDoc("tdf54819b.odt");
1545 SwDoc* pDoc = getSwDoc();
1547 // heading
1548 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
1549 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1550 CPPUNIT_ASSERT_EQUAL(OUString("Outline"),
1551 getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
1553 // next paragraph: bulleted list item
1555 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1556 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
1557 OUString sNumName = getProperty<OUString>(getParagraph(3), "NumberingStyleName");
1558 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1559 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1561 // third paragraph: normal text without numbering
1563 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1564 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
1565 sNumName = getProperty<OUString>(getParagraph(4), "NumberingStyleName");
1566 CPPUNIT_ASSERT_MESSAGE("Bad numbering", sNumName.isEmpty());
1568 //turn on red-lining and show changes
1569 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1570 | RedlineFlags::ShowInsert);
1571 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On);
1572 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1573 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1574 CPPUNIT_ASSERT_MESSAGE("redlines shouldn't be visible",
1575 !IDocumentRedlineAccess::IsShowChanges(
1576 pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1578 // remove only end part of the heading and the next numbered paragraph with paragraph break
1579 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1581 pWrtShell->Down(/*bSelect=*/false);
1582 pWrtShell->Down(/*bSelect=*/false);
1583 pWrtShell->Down(/*bSelect=*/false);
1584 pWrtShell->Down(/*bSelect=*/false);
1585 pWrtShell->Down(/*bSelect=*/false);
1586 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 6, /*bBasicCall=*/false);
1587 pWrtShell->EndPara(/*bSelect=*/true);
1588 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 2, /*bBasicCall=*/false);
1589 pWrtShell->EndPara(/*bSelect=*/true);
1590 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1591 dispatchCommand(mxComponent, ".uno:Cut", {});
1593 // solved problem: changing paragraph style after deletion
1594 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
1595 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1597 // solved problem: apply numbering
1598 CPPUNIT_ASSERT_EQUAL(OUString("Outline"),
1599 getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
1601 // reject deletion
1602 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
1603 rIDRA.AcceptAllRedline(false);
1605 // heading
1607 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
1608 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
1609 CPPUNIT_ASSERT_EQUAL(OUString("Outline"),
1610 getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
1612 // next paragraph: bulleted list item
1614 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1615 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
1616 sNumName = getProperty<OUString>(getParagraph(3), "NumberingStyleName");
1617 CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty());
1618 CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline");
1620 // third paragraph: normal text without numbering
1622 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
1623 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
1624 sNumName = getProperty<OUString>(getParagraph(4), "NumberingStyleName");
1625 CPPUNIT_ASSERT_MESSAGE("Bad numbering", sNumName.isEmpty());
1628 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf140077)
1630 createSwDoc();
1631 SwDoc* const pDoc = getSwDoc();
1633 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1635 // hide
1636 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
1638 pWrtShell->Insert("a");
1639 pWrtShell->SplitNode();
1640 pWrtShell->Insert("b");
1641 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1642 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1643 // enable
1644 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
1646 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1647 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1648 CPPUNIT_ASSERT_MESSAGE(
1649 "redlines should be visible",
1650 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1651 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
1653 pWrtShell->Delete();
1654 pWrtShell->SttEndDoc(/*bStart=*/false);
1655 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1656 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
1658 // crashed in layout
1659 pWrtShell->SplitNode();
1661 pWrtShell->Undo();
1662 pWrtShell->Redo();
1663 pWrtShell->Undo();
1664 pWrtShell->Redo();
1667 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf109376_redline)
1669 createSwDoc();
1670 SwDoc* pDoc = getSwDoc();
1671 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1672 CPPUNIT_ASSERT(pWrtShell);
1673 // need 2 paragraphs to get to the bMoveNds case
1674 pWrtShell->Insert("foo");
1675 pWrtShell->SplitNode();
1676 pWrtShell->Insert("bar");
1677 pWrtShell->SplitNode();
1678 pWrtShell->StartOfSection(false);
1680 // add AT_PARA fly at 1st to be deleted node
1681 SwFormatAnchor anchor(RndStdIds::FLY_AT_PARA);
1682 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
1683 SfxItemSet flySet(pDoc->GetAttrPool(),
1684 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
1685 flySet.Put(anchor);
1686 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
1687 flySet.Put(size); // set a size, else we get 1 char per line...
1688 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
1689 CPPUNIT_ASSERT(pFly != nullptr);
1691 pWrtShell->SttEndDoc(false);
1692 SwInsertTableOptions tableOpt(SwInsertTableFlags::DefaultBorder, 0);
1693 const SwTable& rTable = pWrtShell->InsertTable(tableOpt, 1, 1);
1695 pWrtShell->StartOfSection(false);
1696 SwPaM pam(*pWrtShell->GetCursor()->GetPoint());
1697 pam.SetMark();
1698 pam.GetPoint()->Assign(*rTable.GetTableNode());
1699 pam.Exchange(); // same selection direction as in doc compare...
1701 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
1702 rIDRA.SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert | RedlineFlags::ShowDelete);
1703 rIDRA.AppendRedline(new SwRangeRedline(RedlineType::Delete, pam), true);
1704 // this used to assert/crash with m_pAnchoredFlys mismatch because the
1705 // fly was not deleted but its anchor was moved to the SwTableNode
1706 rIDRA.AcceptAllRedline(true);
1708 CPPUNIT_ASSERT_EQUAL(size_t(0), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1709 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1710 rUndoManager.Undo();
1711 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1712 rUndoManager.Redo();
1713 CPPUNIT_ASSERT_EQUAL(size_t(0), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1714 rUndoManager.Undo();
1715 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1718 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf109376)
1720 createSwDoc();
1721 SwDoc* pDoc = getSwDoc();
1722 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1723 CPPUNIT_ASSERT(pWrtShell);
1724 // need 2 paragraphs to get to the bMoveNds case
1725 pWrtShell->Insert("foo");
1726 pWrtShell->SplitNode();
1727 pWrtShell->Insert("bar");
1728 pWrtShell->SplitNode();
1729 pWrtShell->StartOfSection(false);
1731 // add AT_PARA fly at 1st to be deleted node
1732 SwFormatAnchor anchor(RndStdIds::FLY_AT_PARA);
1733 anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
1734 SfxItemSet flySet(pDoc->GetAttrPool(),
1735 svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>);
1736 flySet.Put(anchor);
1737 SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
1738 flySet.Put(size); // set a size, else we get 1 char per line...
1739 SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
1740 CPPUNIT_ASSERT(pFly != nullptr);
1742 pWrtShell->SttEndDoc(false);
1743 SwInsertTableOptions tableOpt(SwInsertTableFlags::DefaultBorder, 0);
1744 const SwTable& rTable = pWrtShell->InsertTable(tableOpt, 1, 1);
1746 pWrtShell->StartOfSection(false);
1747 SwPaM pam(*pWrtShell->GetCursor()->GetPoint());
1748 pam.SetMark();
1749 pam.GetPoint()->Assign(*rTable.GetTableNode());
1750 pam.Exchange(); // same selection direction as in doc compare...
1752 // this used to assert/crash with m_pAnchoredFlys mismatch because the
1753 // fly was not deleted but its anchor was moved to the SwTableNode
1754 pDoc->getIDocumentContentOperations().DeleteRange(pam);
1755 CPPUNIT_ASSERT_EQUAL(size_t(0), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1756 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1757 rUndoManager.Undo();
1758 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1759 rUndoManager.Redo();
1760 CPPUNIT_ASSERT_EQUAL(size_t(0), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1761 rUndoManager.Undo();
1762 CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
1765 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf147414)
1767 createSwDoc();
1768 SwDoc* pDoc = getSwDoc();
1769 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1770 SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect());
1772 pWrtShell->Insert("Abc");
1774 // hide and enable
1775 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
1776 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
1778 CPPUNIT_ASSERT(pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1779 CPPUNIT_ASSERT(
1780 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1781 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
1783 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1784 // backspace
1785 pWrtShell->DelLeft();
1786 pWrtShell->AutoCorrect(corr, u' ');
1788 // problem was this was 1 i.e. before the deleted "b" while " " was inserted after
1789 CPPUNIT_ASSERT_EQUAL(sal_Int32(3),
1790 pWrtShell->getShellCursor(false)->GetPoint()->GetContentIndex());
1791 CPPUNIT_ASSERT_EQUAL(
1792 OUString("Ab c"),
1793 pWrtShell->getShellCursor(false)->GetPoint()->GetNode().GetTextNode()->GetText());
1796 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf147310)
1798 createSwDoc();
1799 SwDoc* pDoc = getSwDoc();
1800 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1801 CPPUNIT_ASSERT(pWrtShell);
1803 // somehow bug happens only with 2 tables
1804 SwInsertTableOptions tableOpt(SwInsertTableFlags::DefaultBorder, 0);
1805 pWrtShell->InsertTable(tableOpt, 1, 1);
1806 pWrtShell->InsertTable(tableOpt, 1, 1);
1808 pWrtShell->SttEndDoc(/*bStart=*/true);
1810 pWrtShell->DeleteRow(false);
1811 pWrtShell->DeleteRow(false);
1814 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1815 assertXPath(pXmlDoc, "/root/page/body/tab", 0);
1816 discardDumpedLayout();
1818 pWrtShell->Undo();
1819 // this did not create frames for the table
1820 pWrtShell->Undo();
1822 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1823 // there are 2 tables
1824 assertXPath(pXmlDoc, "/root/page/body/tab", 2);
1825 discardDumpedLayout();
1827 pWrtShell->Redo();
1828 pWrtShell->Redo();
1830 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1831 assertXPath(pXmlDoc, "/root/page/body/tab", 0);
1832 discardDumpedLayout();
1834 pWrtShell->Undo();
1835 pWrtShell->Undo();
1837 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1838 // there are 2 tables
1839 assertXPath(pXmlDoc, "/root/page/body/tab", 2);
1843 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf64242_optimizeTable)
1845 createSwDoc("tdf64242_optimizeTable.odt");
1846 SwDoc* pDoc = getSwDoc();
1847 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1849 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1850 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
1851 uno::UNO_QUERY);
1852 uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
1853 uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows();
1855 double origWidth = getProperty<double>(xTextTable, "Width");
1856 sal_Int32 nToleranceW = origWidth * .01;
1857 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table Width", double(17013), origWidth, nToleranceW);
1859 pWrtShell->SelTable(); //select the whole table
1861 dispatchCommand(mxComponent, ".uno:SetOptimalColumnWidth", {});
1862 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table Width: optimize", origWidth,
1863 getProperty<double>(xTextTable, "Width"), nToleranceW);
1865 dispatchCommand(mxComponent, ".uno:SetMinimalColumnWidth", {});
1866 CPPUNIT_ASSERT_MESSAGE("Table Width: minimized",
1867 (origWidth - nToleranceW) > getProperty<double>(xTextTable, "Width"));
1869 double origRowHeight = getProperty<double>(xTableRows->getByIndex(2), "Height");
1870 sal_Int32 nToleranceH = origRowHeight * .01;
1871 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Row Height", double(3441), origRowHeight, nToleranceH);
1873 dispatchCommand(mxComponent, ".uno:SetOptimalRowHeight", {});
1874 double optimalRowHeight = getProperty<double>(xTableRows->getByIndex(2), "Height");
1875 CPPUNIT_ASSERT_MESSAGE("Row Height: optimized",
1876 (origRowHeight - nToleranceH) > optimalRowHeight);
1878 dispatchCommand(mxComponent, ".uno:SetMinimalRowHeight", {});
1879 double minimalRowHeight = getProperty<double>(xTableRows->getByIndex(2), "Height");
1880 CPPUNIT_ASSERT_MESSAGE("Row Height: minimized",
1881 (optimalRowHeight - nToleranceH) > minimalRowHeight);
1882 CPPUNIT_ASSERT_EQUAL_MESSAGE("Row set to auto-height", double(0), minimalRowHeight);
1885 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf45525)
1887 createSwDoc("tdf45525.odt");
1888 SwDoc* pDoc = getSwDoc();
1889 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1891 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1892 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
1893 uno::UNO_QUERY);
1894 uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
1895 uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows();
1897 CPPUNIT_ASSERT_EQUAL(3889.0, getProperty<double>(xTableRows->getByIndex(0), "Height"));
1898 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(1), "Height"));
1899 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(2), "Height"));
1900 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(3), "Height"));
1901 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(4), "Height"));
1903 //Select three cells in the first column
1904 pWrtShell->Down(/*bSelect=*/true);
1905 pWrtShell->Down(/*bSelect=*/true);
1907 dispatchCommand(mxComponent, ".uno:SetOptimalRowHeight", {});
1909 // Without the fix in place, this test would have failed with
1910 // - Expected: 1914
1911 // - Actual : 3889
1912 CPPUNIT_ASSERT_EQUAL(1914.0, getProperty<double>(xTableRows->getByIndex(0), "Height"));
1913 CPPUNIT_ASSERT_EQUAL(1914.0, getProperty<double>(xTableRows->getByIndex(1), "Height"));
1914 CPPUNIT_ASSERT_EQUAL(1914.0, getProperty<double>(xTableRows->getByIndex(2), "Height"));
1915 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(3), "Height"));
1916 CPPUNIT_ASSERT_EQUAL(0.0, getProperty<double>(xTableRows->getByIndex(4), "Height"));
1919 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf126784_distributeSelectedColumns)
1921 createSwDoc("tdf126784_distributeSelectedColumns.odt");
1922 SwDoc* pDoc = getSwDoc();
1923 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1925 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1926 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
1927 uno::UNO_QUERY);
1928 uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
1929 uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows();
1931 auto aSeq = getProperty<uno::Sequence<text::TableColumnSeparator>>(xTableRows->getByIndex(0),
1932 "TableColumnSeparators");
1933 sal_Int16 nOrigCol2Pos = aSeq[0].Position;
1934 sal_Int16 nOrigCol3Pos = aSeq[1].Position;
1936 //Select column 1 and 2
1937 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1939 dispatchCommand(mxComponent, ".uno:DistributeColumns", {});
1941 aSeq = getProperty<uno::Sequence<text::TableColumnSeparator>>(xTableRows->getByIndex(0),
1942 "TableColumnSeparators");
1943 CPPUNIT_ASSERT_MESSAGE("Second column should shrink", nOrigCol2Pos < aSeq[0].Position);
1944 CPPUNIT_ASSERT_EQUAL_MESSAGE("Last column shouldn't change", nOrigCol3Pos, aSeq[1].Position);
1947 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf144317)
1949 createSwDoc("tdf144317.odt");
1950 SwDoc* pDoc = getSwDoc();
1951 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1953 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1954 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
1955 uno::UNO_QUERY);
1956 uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
1957 uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows();
1959 auto aSeq = getProperty<uno::Sequence<text::TableColumnSeparator>>(xTableRows->getByIndex(0),
1960 "TableColumnSeparators");
1961 sal_Int16 nOrigCol1Pos = aSeq[0].Position;
1963 // Move the cursor inside the table
1964 pWrtShell->Down(/*bSelect=*/false);
1966 //Select some cells in the first column
1967 pWrtShell->Down(/*bSelect=*/true);
1968 pWrtShell->Down(/*bSelect=*/true);
1969 pWrtShell->Down(/*bSelect=*/true);
1971 dispatchCommand(mxComponent, ".uno:SetMinimalColumnWidth", {});
1973 aSeq = getProperty<uno::Sequence<text::TableColumnSeparator>>(xTableRows->getByIndex(0),
1974 "TableColumnSeparators");
1975 CPPUNIT_ASSERT_MESSAGE("First column should shrink", aSeq[0].Position < nOrigCol1Pos);
1978 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf108687_tabstop)
1980 createSwDoc("tdf108687_tabstop.odt");
1981 SwDoc* pDoc = getSwDoc();
1982 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1983 SwNodeOffset nStartIndex = pWrtShell->GetCursor()->GetPointNode().GetIndex();
1984 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(9), nStartIndex);
1986 // Now pressing 'tab' should jump to the radio buttons.
1987 SwXTextDocument* pXTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get());
1988 CPPUNIT_ASSERT(pXTextDocument);
1989 pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
1990 pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_TAB);
1991 Scheduler::ProcessEventsToIdle();
1992 //sal_Int32 nEndIndex = pWrtShell->GetCursor()->GetNode().GetIndex();
1993 //CPPUNIT_ASSERT_EQUAL(sal_Int32(11), nEndIndex);
1996 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119571)
1998 createSwDoc("tdf54819.fodt");
1999 SwDoc* pDoc = getSwDoc();
2001 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
2002 getProperty<OUString>(getParagraph(1), "ParaStyleName"));
2003 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
2004 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
2006 //turn on red-lining and show changes
2007 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
2008 | RedlineFlags::ShowInsert);
2009 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2010 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2011 CPPUNIT_ASSERT_MESSAGE(
2012 "redlines should be visible",
2013 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2015 // join paragraphs by removing the end of the first one with paragraph break
2016 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2017 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
2018 pWrtShell->EndPara(/*bSelect=*/true);
2019 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
2020 dispatchCommand(mxComponent, ".uno:Cut", {});
2022 // second paragraph changes its style in "Show changes" mode
2023 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
2024 getProperty<OUString>(getParagraph(1), "ParaStyleName"));
2025 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
2026 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
2029 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf144058)
2031 createSwDoc("tdf144058.fodt");
2032 SwDoc* pDoc = getSwDoc();
2034 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
2035 getProperty<OUString>(getParagraph(1), "ParaStyleName"));
2037 //turn on red-lining and show changes
2038 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
2039 | RedlineFlags::ShowInsert);
2040 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2041 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2042 CPPUNIT_ASSERT_MESSAGE(
2043 "redlines should be visible",
2044 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2046 // join first and last but one paragraphs by removing the end of the first paragraph
2047 // with paragraph break, and by removing two tables of the selected range completely
2048 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2049 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
2050 pWrtShell->Down(/*bSelect=*/true);
2051 pWrtShell->Down(/*bSelect=*/true);
2052 pWrtShell->Down(/*bSelect=*/true);
2053 dispatchCommand(mxComponent, ".uno:Cut", {});
2055 // accept all: tables are deleted
2056 dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {});
2058 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
2059 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
2060 uno::UNO_QUERY);
2061 // This was 2 (remaining empty tables)
2062 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
2065 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf147507)
2067 createSwDoc("tdf147507.fodt");
2068 SwDoc* pDoc = getSwDoc();
2070 // turn on red-lining and show changes
2071 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
2072 | RedlineFlags::ShowInsert);
2073 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2074 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2075 CPPUNIT_ASSERT_MESSAGE(
2076 "redlines should be visible",
2077 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2079 // select all, backspace and reject all crashed
2080 dispatchCommand(mxComponent, ".uno:SelectAll", {});
2081 dispatchCommand(mxComponent, ".uno:SwBackSpace", {});
2082 dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
2085 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119019)
2087 // check handling of overlapping redlines
2088 createSwDoc("tdf119019.docx");
2089 SwDoc* pDoc = getSwDoc();
2091 CPPUNIT_ASSERT_EQUAL(OUString("Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus."),
2092 getParagraph(2)->getString());
2093 CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(2), 1)->getString());
2094 // second paragraph has got a tracked paragraph formatting at this point
2095 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(2), 1), "RedlineType"));
2097 // delete last word of the second paragraph to remove tracked paragraph formatting
2098 // of this paragraph to track and show word deletion correctly.
2099 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2100 pWrtShell->Down(/*bSelect=*/false);
2101 pWrtShell->Down(/*bSelect=*/false);
2102 pWrtShell->Down(/*bSelect=*/false);
2103 pWrtShell->EndPara(/*bSelect=*/false);
2104 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 7, /*bBasicCall=*/false);
2105 dispatchCommand(mxComponent, ".uno:Cut", {});
2107 // check tracked text deletion
2108 CPPUNIT_ASSERT_EQUAL(OUString("tellus."), getRun(getParagraph(2), 3)->getString());
2109 CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(2), 2)->getString());
2110 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(2), 2), "RedlineType"));
2112 // make sure that the tracked paragraph formatting is removed
2113 CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(2), 1), "RedlineType"));
2116 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119824)
2118 // check handling of overlapping redlines with Redo
2119 createSwDoc("tdf119019.docx");
2120 SwDoc* pDoc = getSwDoc();
2122 CPPUNIT_ASSERT_EQUAL(OUString("Pellentesque habitant morbi tristique senectus "
2123 "et netus et malesuada fames ac turpis egestas. "
2124 "Proin pharetra nonummy pede. Mauris et orci."),
2125 getParagraph(3)->getString());
2126 CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(3), 1)->getString());
2127 // third paragraph has got a tracked paragraph formatting at this point
2128 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 1), "RedlineType"));
2130 // and a tracked text deletion at the beginning of the paragraph
2131 CPPUNIT_ASSERT_EQUAL(OUString("Pellentesque habitant morbi tristique senectus "),
2132 getRun(getParagraph(3), 3)->getString());
2133 CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(3), 2)->getString());
2134 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 2), "RedlineType"));
2136 // delete last word of the third paragraph to remove tracked paragraph formatting
2137 // of this paragraph to track and show word deletion correctly.
2138 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2139 pWrtShell->Down(/*bSelect=*/false);
2140 pWrtShell->Down(/*bSelect=*/false);
2141 pWrtShell->Down(/*bSelect=*/false);
2142 pWrtShell->Down(/*bSelect=*/false);
2143 pWrtShell->EndPara(/*bSelect=*/false);
2144 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 5, /*bBasicCall=*/false);
2145 dispatchCommand(mxComponent, ".uno:Cut", {});
2147 // check tracking of the new text deletion
2148 CPPUNIT_ASSERT_EQUAL(OUString("orci."), getRun(getParagraph(3), 7)->getString());
2149 CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(3), 6)->getString());
2150 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 6), "RedlineType"));
2152 // make sure that the tracked paragraph formatting is removed (tracked deletion is in the second run)
2153 CPPUNIT_ASSERT_EQUAL(OUString("Pellentesque habitant morbi tristique senectus "),
2154 getRun(getParagraph(3), 2)->getString());
2155 CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(3), 1)->getString());
2156 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 1), "RedlineType"));
2158 // tdf#119824 check redo
2159 sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
2160 rUndoManager.Undo();
2161 rUndoManager.Undo();
2162 rUndoManager.Redo();
2163 rUndoManager.Redo();
2165 // check again the first tracked text deletion (we lost this before the redo fix)
2166 CPPUNIT_ASSERT_EQUAL(OUString("Pellentesque habitant morbi tristique senectus "),
2167 getRun(getParagraph(3), 2)->getString());
2168 CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(3), 1)->getString());
2169 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 1), "RedlineType"));
2171 // check redo of the new tracked text deletion
2172 CPPUNIT_ASSERT_EQUAL(OUString("orci."), getRun(getParagraph(3), 7)->getString());
2173 CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(3), 6)->getString());
2174 CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 6), "RedlineType"));
2177 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf105413)
2179 createSwDoc("tdf105413.fodt");
2180 SwDoc* pDoc = getSwDoc();
2182 // all paragraphs have got Standard paragraph style
2183 for (int i = 1; i < 4; ++i)
2185 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
2186 getProperty<OUString>(getParagraph(i), "ParaStyleName"));
2189 // turn on red-lining and show changes
2190 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
2191 | RedlineFlags::ShowDelete);
2192 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2193 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2194 CPPUNIT_ASSERT_MESSAGE(
2195 "redlines should be visible",
2196 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2198 // Set Heading 1 paragraph style in the 3th paragraph.
2199 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2200 pWrtShell->Down(/*bSelect=*/false);
2201 pWrtShell->Down(/*bSelect=*/false);
2202 pWrtShell->EndPara(/*bSelect=*/false);
2204 uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence({
2205 { "Style", uno::Any(OUString("Heading 1")) },
2206 { "FamilyName", uno::Any(OUString("ParagraphStyles")) },
2208 dispatchCommand(mxComponent, ".uno:StyleApply", aPropertyValues);
2210 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
2211 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
2212 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
2213 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
2216 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf76817)
2218 createSwDoc("num-parent-style.docx");
2219 SwDoc* pDoc = getSwDoc();
2221 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2222 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
2223 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2224 getProperty<sal_Int32>(getParagraph(2), "OutlineLevel"));
2225 CPPUNIT_ASSERT_EQUAL(OUString("1.1"),
2226 getProperty<OUString>(getParagraph(2), "ListLabelString"));
2228 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2229 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
2230 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2231 getProperty<sal_Int32>(getParagraph(4), "OutlineLevel"));
2232 CPPUNIT_ASSERT_EQUAL(OUString("2.1"),
2233 getProperty<OUString>(getParagraph(4), "ListLabelString"));
2235 // set Heading 2 style of paragraph 2 to Heading 1
2237 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2238 pWrtShell->Down(/*bSelect=*/false);
2240 uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence({
2241 { "Style", uno::Any(OUString("Heading 1")) },
2242 { "FamilyName", uno::Any(OUString("ParagraphStyles")) },
2244 dispatchCommand(mxComponent, ".uno:StyleApply", aPropertyValues);
2246 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
2247 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
2248 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2249 getProperty<sal_Int32>(getParagraph(2), "OutlineLevel"));
2250 // This was "1 Heading" instead of "2 Heading"
2251 CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty<OUString>(getParagraph(2), "ListLabelString"));
2253 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2254 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
2255 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2256 getProperty<sal_Int32>(getParagraph(4), "OutlineLevel"));
2257 // This was "2.1 Heading"
2258 CPPUNIT_ASSERT_EQUAL(OUString("3.1"),
2259 getProperty<OUString>(getParagraph(4), "ListLabelString"));
2261 // set Heading 1 style of paragraph 3 to Heading 2
2263 pWrtShell->Down(/*bSelect=*/false);
2265 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
2266 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
2267 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2268 getProperty<sal_Int32>(getParagraph(3), "OutlineLevel"));
2269 CPPUNIT_ASSERT_EQUAL(OUString("3"), getProperty<OUString>(getParagraph(3), "ListLabelString"));
2271 uno::Sequence<beans::PropertyValue> aPropertyValues2 = comphelper::InitPropertySequence({
2272 { "Style", uno::Any(OUString("Heading 2")) },
2273 { "FamilyName", uno::Any(OUString("ParagraphStyles")) },
2275 dispatchCommand(mxComponent, ".uno:StyleApply", aPropertyValues2);
2277 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2278 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
2279 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2280 getProperty<sal_Int32>(getParagraph(3), "OutlineLevel"));
2281 CPPUNIT_ASSERT_EQUAL(OUString("2.1"),
2282 getProperty<OUString>(getParagraph(3), "ListLabelString"));
2284 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2285 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
2286 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2287 getProperty<sal_Int32>(getParagraph(4), "OutlineLevel"));
2288 CPPUNIT_ASSERT_EQUAL(OUString("2.2"),
2289 getProperty<OUString>(getParagraph(4), "ListLabelString"));
2292 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf76817_round_trip)
2294 createSwDoc("tdf76817.fodt");
2296 // save it to DOCX
2297 saveAndReload("Office Open XML Text");
2299 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
2300 SwViewShell* pViewShell
2301 = pTextDoc->GetDocShell()->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
2302 pViewShell->Reformat();
2304 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2305 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
2306 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2307 getProperty<sal_Int32>(getParagraph(2), "OutlineLevel"));
2308 CPPUNIT_ASSERT_EQUAL(OUString("1.1"),
2309 getProperty<OUString>(getParagraph(2), "ListLabelString"));
2311 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2312 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
2313 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2314 getProperty<sal_Int32>(getParagraph(4), "OutlineLevel"));
2315 CPPUNIT_ASSERT_EQUAL(OUString("2.1"),
2316 getProperty<OUString>(getParagraph(4), "ListLabelString"));
2318 // set Heading 2 style of paragraph 2 to Heading 1
2320 SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
2321 pWrtShell->Down(/*bSelect=*/false);
2323 uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence({
2324 { "Style", uno::Any(OUString("Heading 1")) },
2325 { "FamilyName", uno::Any(OUString("ParagraphStyles")) },
2327 dispatchCommand(mxComponent, ".uno:StyleApply", aPropertyValues);
2329 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
2330 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
2331 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2332 getProperty<sal_Int32>(getParagraph(2), "OutlineLevel"));
2333 // This was "1 Heading" instead of "2 Heading"
2334 CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty<OUString>(getParagraph(2), "ListLabelString"));
2336 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2337 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
2338 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2339 getProperty<sal_Int32>(getParagraph(4), "OutlineLevel"));
2340 // This was "2.1 Heading"
2341 CPPUNIT_ASSERT_EQUAL(OUString("3.1"),
2342 getProperty<OUString>(getParagraph(4), "ListLabelString"));
2344 // set Heading 1 style of paragraph 3 to Heading 2
2346 pWrtShell->Down(/*bSelect=*/false);
2348 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
2349 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
2350 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2351 getProperty<sal_Int32>(getParagraph(3), "OutlineLevel"));
2352 CPPUNIT_ASSERT_EQUAL(OUString("3"), getProperty<OUString>(getParagraph(3), "ListLabelString"));
2354 uno::Sequence<beans::PropertyValue> aPropertyValues2 = comphelper::InitPropertySequence({
2355 { "Style", uno::Any(OUString("Heading 2")) },
2356 { "FamilyName", uno::Any(OUString("ParagraphStyles")) },
2358 dispatchCommand(mxComponent, ".uno:StyleApply", aPropertyValues2);
2360 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2361 getProperty<OUString>(getParagraph(3), "ParaStyleName"));
2362 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2363 getProperty<sal_Int32>(getParagraph(3), "OutlineLevel"));
2364 CPPUNIT_ASSERT_EQUAL(OUString("2.1"),
2365 getProperty<OUString>(getParagraph(3), "ListLabelString"));
2367 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2368 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
2369 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2370 getProperty<sal_Int32>(getParagraph(4), "OutlineLevel"));
2371 CPPUNIT_ASSERT_EQUAL(OUString("2.2"),
2372 getProperty<OUString>(getParagraph(4), "ListLabelString"));
2375 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf76817_custom_outline)
2377 createSwDoc("tdf76817.docx");
2378 SwDoc* pDoc = getSwDoc();
2380 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
2381 getProperty<OUString>(getParagraph(1), "ParaStyleName"));
2382 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2383 getProperty<sal_Int32>(getParagraph(1), "OutlineLevel"));
2384 CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(getParagraph(1), "ListLabelString"));
2386 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2387 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
2388 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2389 getProperty<sal_Int32>(getParagraph(2), "OutlineLevel"));
2390 // This wasn't numbered
2391 CPPUNIT_ASSERT_EQUAL(OUString("1.1"),
2392 getProperty<OUString>(getParagraph(2), "ListLabelString"));
2394 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2395 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
2396 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2397 getProperty<sal_Int32>(getParagraph(4), "OutlineLevel"));
2398 // This wasn't numbered
2399 CPPUNIT_ASSERT_EQUAL(OUString("2.1"),
2400 getProperty<OUString>(getParagraph(4), "ListLabelString"));
2402 // set Heading 2 style of paragraph 2 to Heading 1
2404 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2405 pWrtShell->Down(/*bSelect=*/false);
2407 uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence({
2408 { "Style", uno::Any(OUString("Heading 1")) },
2409 { "FamilyName", uno::Any(OUString("ParagraphStyles")) },
2411 dispatchCommand(mxComponent, ".uno:StyleApply", aPropertyValues);
2413 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
2414 getProperty<OUString>(getParagraph(2), "ParaStyleName"));
2415 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
2416 getProperty<sal_Int32>(getParagraph(2), "OutlineLevel"));
2417 CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty<OUString>(getParagraph(2), "ListLabelString"));
2419 CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"),
2420 getProperty<OUString>(getParagraph(4), "ParaStyleName"));
2421 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
2422 getProperty<sal_Int32>(getParagraph(4), "OutlineLevel"));
2423 // This wasn't numbered
2424 CPPUNIT_ASSERT_EQUAL(OUString("3.1"),
2425 getProperty<OUString>(getParagraph(4), "ListLabelString"));
2428 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf123102)
2430 createSwDoc("tdf123102.odt");
2431 // insert a new row after a vertically merged cell
2432 dispatchCommand(mxComponent, ".uno:InsertRowsAfter", {});
2433 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
2434 // This was "3." - caused by the hidden numbered paragraph of the new merged cell
2435 assertXPath(pXmlDoc,
2436 "/root/page/body/tab/row[6]/cell[1]/txt/SwParaPortion/SwLineLayout/SwFieldPortion",
2437 "expand", "2.");
2440 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testUnfloatButtonSmallTable)
2442 // The floating table in the test document is too small, so we don't provide an unfloat button
2443 createSwDoc("small_floating_table.odt");
2444 SwDoc* pDoc = getSwDoc();
2445 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2446 CPPUNIT_ASSERT(pWrtShell);
2448 const SwSortedObjs* pAnchored
2449 = pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs();
2450 CPPUNIT_ASSERT(pAnchored);
2451 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pAnchored->size());
2452 SwAnchoredObject* pAnchoredObj = (*pAnchored)[0];
2454 SwFlyFrame* pFlyFrame = pAnchoredObj->DynCastFlyFrame();
2455 CPPUNIT_ASSERT(pFlyFrame);
2456 CPPUNIT_ASSERT(!pFlyFrame->IsShowUnfloatButton(pWrtShell));
2458 SdrObject* pObj = pFlyFrame->GetFormat()->FindRealSdrObject();
2459 CPPUNIT_ASSERT(pObj);
2460 pWrtShell->SelectObj(Point(), 0, pObj);
2461 CPPUNIT_ASSERT(!pFlyFrame->IsShowUnfloatButton(pWrtShell));
2464 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testUnfloatButton)
2466 // Different use cases where unfloat button should be visible
2467 const std::vector<OUString> aTestFiles = {
2468 "unfloatable_floating_table.odt", // Typical use case of multipage floating table
2471 for (const OUString& aTestFile : aTestFiles)
2473 OString sTestFileName = OUStringToOString(aTestFile, RTL_TEXTENCODING_UTF8);
2474 OString sFailureMessage = OString::Concat("Failure in the test file: ") + sTestFileName;
2476 createSwDoc(sTestFileName.getStr());
2477 SwDoc* pDoc = getSwDoc();
2478 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2479 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pWrtShell);
2481 const SwSortedObjs* pAnchored;
2482 pAnchored = pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs();
2483 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pAnchored);
2484 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailureMessage.getStr(), static_cast<size_t>(1),
2485 pAnchored->size());
2486 SwAnchoredObject* pAnchoredObj = (*pAnchored)[0];
2488 // The unfloat button is not visible until it gets selected
2489 SwFlyFrame* pFlyFrame = pAnchoredObj->DynCastFlyFrame();
2490 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pFlyFrame);
2491 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(),
2492 !pFlyFrame->IsShowUnfloatButton(pWrtShell));
2494 SdrObject* pObj = pFlyFrame->GetFormat()->FindRealSdrObject();
2495 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pObj);
2496 pWrtShell->SelectObj(Point(), 0, pObj);
2497 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pFlyFrame->IsShowUnfloatButton(pWrtShell));
2501 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testUnfloatButtonReadOnlyMode)
2503 // In read only mode we don't show the unfloat button even if we have a multipage floating table
2504 createSwDoc("unfloatable_floating_table.odt");
2505 SwDoc* pDoc = getSwDoc();
2506 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2507 CPPUNIT_ASSERT(pWrtShell);
2508 pWrtShell->SetReadonlyOption(true);
2510 const SwSortedObjs* pAnchored
2511 = pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs();
2512 CPPUNIT_ASSERT(pAnchored);
2513 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pAnchored->size());
2514 SwAnchoredObject* pAnchoredObj = (*pAnchored)[0];
2516 SwFlyFrame* pFlyFrame = pAnchoredObj->DynCastFlyFrame();
2517 CPPUNIT_ASSERT(pFlyFrame);
2518 CPPUNIT_ASSERT(!pFlyFrame->IsShowUnfloatButton(pWrtShell));
2520 SdrObject* pObj = pFlyFrame->GetFormat()->FindRealSdrObject();
2521 CPPUNIT_ASSERT(pObj);
2522 pWrtShell->SelectObj(Point(), 0, pObj);
2523 CPPUNIT_ASSERT(!pFlyFrame->IsShowUnfloatButton(pWrtShell));
2526 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testUnfloating)
2528 // Test unfloating with tables imported from different file formats
2529 const std::vector<OUString> aTestFiles = {
2530 "unfloatable_floating_table.odt",
2533 for (const OUString& aTestFile : aTestFiles)
2535 OString sTestFileName = OUStringToOString(aTestFile, RTL_TEXTENCODING_UTF8);
2536 OString sFailureMessage = OString::Concat("Failure in the test file: ") + sTestFileName;
2538 // Test what happens when pushing the unfloat button
2539 createSwDoc(sTestFileName.getStr());
2540 SwDoc* pDoc = getSwDoc();
2541 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2542 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pWrtShell);
2544 SwFlyFrame* pFlyFrame;
2546 // Before unfloating we have only one page with a fly frame
2548 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailureMessage.getStr(), SwFrameType::Page,
2549 pWrtShell->GetLayout()->GetLower()->GetType());
2550 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(),
2551 !pWrtShell->GetLayout()->GetLower()->GetNext());
2552 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2553 sFailureMessage.getStr(), SwFrameType::Txt,
2554 pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetType());
2555 const SwSortedObjs* pAnchored
2556 = pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs();
2557 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pAnchored);
2558 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailureMessage.getStr(), static_cast<size_t>(1),
2559 pAnchored->size());
2560 SwAnchoredObject* pAnchoredObj = (*pAnchored)[0];
2561 pFlyFrame = pAnchoredObj->DynCastFlyFrame();
2562 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pFlyFrame);
2565 // Select the floating table
2566 SdrObject* pObj = pFlyFrame->GetFormat()->FindRealSdrObject();
2567 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pObj);
2568 pWrtShell->SelectObj(Point(), 0, pObj);
2569 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(), pFlyFrame->IsShowUnfloatButton(pWrtShell));
2571 // Push the unfloat button
2572 pFlyFrame->ActiveUnfloatButton(pWrtShell);
2573 Scheduler::ProcessEventsToIdle();
2575 // After unfloating we have two pages with one table frame on each page
2576 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(),
2577 pWrtShell->GetLayout()->GetLower()->GetNext());
2578 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailureMessage.getStr(), SwFrameType::Page,
2579 pWrtShell->GetLayout()->GetLower()->GetNext()->GetType());
2580 CPPUNIT_ASSERT_MESSAGE(sFailureMessage.getStr(),
2581 !pWrtShell->GetLayout()->GetLower()->GetNext()->GetNext());
2582 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2583 sFailureMessage.getStr(), SwFrameType::Tab,
2584 pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetType());
2585 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2586 sFailureMessage.getStr(), SwFrameType::Tab,
2587 pWrtShell->GetLayout()->GetLower()->GetNext()->GetLower()->GetLower()->GetType());
2591 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRTLparaStyle_LocaleArabic)
2593 // New documents, created in RTL locales, were not round-tripping the paragraph style as RTL.
2594 // Set the locale to "ar" for this test.
2595 m_aSavedSettings = Application::GetSettings();
2596 AllSettings aSettings(m_aSavedSettings);
2597 aSettings.SetLanguageTag(LanguageTag("ar"));
2598 Application::SetSettings(aSettings);
2599 comphelper::ScopeGuard g([this] { Application::SetSettings(this->m_aSavedSettings); });
2601 createSwDoc(); // new, empty doc - everything defaults to RTL with Arabic locale
2603 // Save it and load it back.
2604 saveAndReload("Office Open XML Text");
2606 uno::Reference<beans::XPropertySet> xPageStyle(
2607 getStyles("ParagraphStyles")->getByName("Default Paragraph Style"), uno::UNO_QUERY_THROW);
2608 // Test the text Direction value for the -none- based paragraph styles
2609 CPPUNIT_ASSERT_EQUAL_MESSAGE("RTL Writing Mode", sal_Int32(1),
2610 getProperty<sal_Int32>(xPageStyle, "WritingMode"));
2613 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf122893)
2615 createSwDoc("tdf105413.fodt");
2616 SwDoc* pDoc = getSwDoc();
2618 // all paragraphs are left-aligned with preset single line spacing
2619 for (int i = 1; i < 4; ++i)
2621 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraph(i), "ParaAdjust"));
2622 dispatchCommand(mxComponent, ".uno:SpacePara1", {});
2625 // turn on red-lining and show changes
2626 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
2627 | RedlineFlags::ShowDelete);
2628 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2629 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2630 CPPUNIT_ASSERT_MESSAGE(
2631 "redlines should be visible",
2632 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2634 // Set center-aligned paragraph with preset double line spacing in the 3th paragraph.
2635 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2636 pWrtShell->Down(/*bSelect=*/false);
2637 pWrtShell->Down(/*bSelect=*/false);
2638 pWrtShell->EndPara(/*bSelect=*/false);
2640 dispatchCommand(mxComponent, ".uno:CenterPara", {});
2641 dispatchCommand(mxComponent, ".uno:SpacePara2", {});
2643 CPPUNIT_ASSERT_EQUAL(sal_Int32(3),
2644 getProperty<sal_Int32>(getParagraph(3), "ParaAdjust")); // center-aligned
2645 CPPUNIT_ASSERT_EQUAL(sal_Int16(200),
2646 getProperty<style::LineSpacing>(getParagraph(3), "ParaLineSpacing")
2647 .Height); // double line spacing
2648 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
2649 getProperty<sal_Int32>(getParagraph(2), "ParaAdjust")); // left-aligned
2650 CPPUNIT_ASSERT_EQUAL(sal_Int16(100),
2651 getProperty<style::LineSpacing>(getParagraph(2), "ParaLineSpacing")
2652 .Height); // single line spacing
2655 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf122901)
2657 createSwDoc("tdf105413.fodt");
2658 SwDoc* pDoc = getSwDoc();
2660 // all paragraphs with zero borders
2661 for (int i = 1; i < 4; ++i)
2663 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
2664 getProperty<sal_Int32>(getParagraph(i), "ParaTopMargin"));
2665 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
2666 getProperty<sal_Int32>(getParagraph(i), "ParaBottomMargin"));
2669 // turn on red-lining and show changes
2670 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
2671 | RedlineFlags::ShowDelete);
2672 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2673 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2674 CPPUNIT_ASSERT_MESSAGE(
2675 "redlines should be visible",
2676 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2678 // Increase paragraph borders in the 3th paragraph, similar to the default icon of the UI
2679 // "Increase Paragraph Spacing".
2680 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2681 pWrtShell->Down(/*bSelect=*/false);
2682 pWrtShell->Down(/*bSelect=*/false);
2683 pWrtShell->EndPara(/*bSelect=*/false);
2685 dispatchCommand(mxComponent, ".uno:ParaspaceIncrease", {});
2687 CPPUNIT_ASSERT_EQUAL(sal_Int32(101), getProperty<sal_Int32>(getParagraph(3), "ParaTopMargin"));
2688 CPPUNIT_ASSERT_EQUAL(sal_Int32(101),
2689 getProperty<sal_Int32>(getParagraph(3), "ParaBottomMargin"));
2690 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraph(2), "ParaTopMargin"));
2691 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraph(2), "ParaBottomMargin"));
2694 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf122942)
2696 createSwDoc("tdf122942.odt");
2697 SwDoc* pDoc = getSwDoc();
2698 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2700 // Do the moral equivalent of mouse button down, move and up.
2701 // Start creating a custom shape that overlaps with the rounded rectangle
2702 // already present in the document.
2703 Point aStartPos(8000, 3000);
2704 pWrtShell->BeginCreate(SdrObjKind::CustomShape, aStartPos);
2706 // Set its size.
2707 Point aMovePos(10000, 5000);
2708 pWrtShell->MoveCreate(aMovePos);
2710 // Finish creation.
2711 pWrtShell->EndCreate(SdrCreateCmd::ForceEnd);
2713 // Make sure that the shape is inserted.
2714 const auto& rFormats = *pDoc->GetSpzFrameFormats();
2715 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rFormats.size());
2717 saveAndReload("writer8");
2718 pDoc = getSwDoc();
2719 const auto& rFormats2 = *pDoc->GetSpzFrameFormats();
2720 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rFormats2.size());
2722 // Make sure the top of the inserted shape does not move outside the existing shape, even after
2723 // reload.
2724 SdrObject* pObject1 = rFormats2[0]->FindSdrObject();
2725 CPPUNIT_ASSERT(pObject1);
2726 const tools::Rectangle& rOutRect1 = pObject1->GetLastBoundRect();
2727 SdrObject* pObject2 = rFormats2[1]->FindSdrObject();
2728 CPPUNIT_ASSERT(pObject2);
2729 const tools::Rectangle& rOutRect2 = pObject2->GetLastBoundRect();
2730 CPPUNIT_ASSERT(rOutRect2.Top() > rOutRect1.Top());
2731 CPPUNIT_ASSERT(rOutRect2.Top() < rOutRect1.Bottom());
2734 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf132160)
2736 createSwDoc("tdf132160.odt");
2738 // this would crash due to delete redline starting with ToX
2739 dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
2741 // this would crash due to insert redline ending on table node
2742 dispatchCommand(mxComponent, ".uno:Undo", {});
2744 dispatchCommand(mxComponent, ".uno:Redo", {});
2746 dispatchCommand(mxComponent, ".uno:Undo", {});
2749 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137526)
2751 createSwDoc("tdf132160.odt");
2752 SwDoc* pDoc = getSwDoc();
2754 // switch on "Show changes in margin" mode
2755 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
2757 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2758 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2760 // select and delete a word
2761 dispatchCommand(mxComponent, ".uno:WordRightSel", {});
2762 dispatchCommand(mxComponent, ".uno:Delete", {});
2763 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("support"));
2765 // this would crash due to bad redline range
2766 dispatchCommand(mxComponent, ".uno:Undo", {});
2767 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Encryption"));
2769 // switch off "Show changes in margin" mode
2770 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
2771 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2774 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137684)
2776 createSwDoc("tdf132160.odt");
2777 SwDoc* pDoc = getSwDoc();
2779 // switch on "Show changes in margin" mode
2780 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
2782 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2783 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2785 // select and delete a word letter by letter
2786 for (int i = 0; i <= 10; ++i)
2788 dispatchCommand(mxComponent, ".uno:Delete", {});
2790 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("support"));
2792 // this would crash due to bad redline range
2793 for (int i = 0; i <= 10; ++i)
2795 dispatchCommand(mxComponent, ".uno:Undo", {});
2797 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Encryption "));
2799 // switch off "Show changes in margin" mode
2800 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
2801 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2804 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137503)
2806 createSwDoc("tdf132160.odt");
2807 SwDoc* pDoc = getSwDoc();
2809 // switch on "Show changes in margin" mode
2810 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
2812 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2813 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2815 // select and delete the first two paragraphs
2816 pWrtShell->EndPara(/*bSelect=*/true);
2817 pWrtShell->EndPara(/*bSelect=*/true);
2818 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
2819 dispatchCommand(mxComponent, ".uno:Delete", {});
2820 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("The"));
2822 // this would crash due to bad redline range
2823 dispatchCommand(mxComponent, ".uno:Undo", {});
2824 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Encryption "));
2826 // this would crash due to bad redline range
2827 dispatchCommand(mxComponent, ".uno:Redo", {});
2828 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("The"));
2830 // switch off "Show changes in margin" mode
2831 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
2832 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2835 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf138605)
2837 createSwDoc();
2838 SwDoc* pDoc = getSwDoc();
2839 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2841 // turn on red-lining and show changes
2842 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
2843 | RedlineFlags::ShowDelete);
2844 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2845 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2846 CPPUNIT_ASSERT_MESSAGE(
2847 "redlines should be visible",
2848 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2850 // insert a word, delete it with change tracking and try to undo it
2851 pWrtShell->Insert("word");
2852 dispatchCommand(mxComponent, ".uno:SelectAll", {});
2853 dispatchCommand(mxComponent, ".uno:Delete", {});
2854 // this crashed due to bad access to the empty redline table
2855 dispatchCommand(mxComponent, ".uno:Undo", {});
2857 // more Undo
2858 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("word"));
2859 dispatchCommand(mxComponent, ".uno:Undo", {});
2860 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith(""));
2861 dispatchCommand(mxComponent, ".uno:Undo", {});
2864 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf138135)
2866 createSwDoc("tdf132160.odt");
2867 SwDoc* pDoc = getSwDoc();
2869 // switch on "Show changes in margin" mode
2870 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
2872 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2873 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2875 // select and delete a word letter by letter by using backspace
2876 dispatchCommand(mxComponent, ".uno:GoToNextWord", {});
2878 for (int i = 0; i <= 10; ++i)
2880 dispatchCommand(mxComponent, ".uno:SwBackspace", {});
2882 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("support"));
2884 // TODO group redlines for managing tracked changes/showing in margin
2885 for (int i = 0; i <= 10; ++i)
2886 dispatchCommand(mxComponent, ".uno:Undo", {});
2888 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Encryption"));
2890 // switch off "Show changes in margin" mode
2891 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
2892 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2895 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf52391)
2897 createSwDoc("tdf52391.fodt");
2899 dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
2901 const uno::Reference<text::XTextRange> xRun = getRun(getParagraph(1), 1);
2902 // this was "Portion1", because the tracked background color of Portion1 was
2903 // accepted for "Reject All". Now rejection clears formatting of the text
2904 // in format-only changes, concatenating the text portions in the first paragraph.
2905 CPPUNIT_ASSERT_EQUAL(OUString("Portion1Portion2"), xRun->getString());
2908 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137771)
2910 createSwDoc("tdf132160.odt");
2911 SwDoc* pDoc = getSwDoc();
2913 // switch on "Show changes in margin" mode
2914 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
2916 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2917 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2919 // delete a word at the end of the paragraph.
2920 dispatchCommand(mxComponent, ".uno:GotoEndOfPara", {});
2921 for (int i = 0; i < 6; ++i)
2923 dispatchCommand(mxComponent, ".uno:SwBackspace", {});
2926 CPPUNIT_ASSERT(getParagraph(1)->getString().endsWith("to be "));
2928 // Dump the rendering of the first page as an XML file.
2929 SwDocShell* pShell = pDoc->GetDocShell();
2930 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
2931 MetafileXmlDump dumper;
2932 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
2933 CPPUNIT_ASSERT(pXmlDoc);
2935 // This would be 5 without the new vertical redline mark
2936 assertXPath(pXmlDoc, "/metafile/push/push/push/line", 6);
2938 // This was the content of the next <text> (missing deletion on margin)
2939 // or only the first character of the deleted character sequence
2940 assertXPathContent(pXmlDoc, "/metafile/push/push/push/textarray[9]/text", " saved.");
2942 // this would crash due to bad redline range
2943 for (int i = 0; i < 6; ++i)
2945 dispatchCommand(mxComponent, ".uno:Undo", {});
2947 CPPUNIT_ASSERT(getParagraph(1)->getString().endsWith("to be saved."));
2949 // switch off "Show changes in margin" mode
2950 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
2951 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
2954 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf142130)
2956 createSwDoc("tdf142130.fodt");
2957 SwDoc* pDoc = getSwDoc();
2959 //turn on red-lining and show changes
2960 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
2961 | RedlineFlags::ShowInsert);
2962 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2963 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
2964 CPPUNIT_ASSERT_MESSAGE(
2965 "redlines should be visible",
2966 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
2968 // Dump the rendering of the first page as an XML file.
2969 SwDocShell* pShell = pDoc->GetDocShell();
2970 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
2971 MetafileXmlDump dumper;
2972 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
2973 CPPUNIT_ASSERT(pXmlDoc);
2975 // This was 6 (bad crossing out of the first, not deleted image)
2976 // (4 lines = 2 lines for crossing out of the second image + 2 lines =
2977 // vertical "changed line" indicator before the two paragraph lines)
2978 assertXPath(pXmlDoc, "/metafile/push/push/push/line", 4);
2980 // check line color
2981 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[1]/linecolor", 5);
2982 // tdf#142128 This was 3 (NON_PRINTING_CHARACTER_COLOR = #268bd2)
2983 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[1]/linecolor[@color='#268bd2']", 0);
2985 // reject deletion of the second image
2986 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
2987 rIDRA.AcceptAllRedline(false);
2989 xMetaFile = pShell->GetPreviewMetaFile();
2990 xmlDocUniquePtr pXmlDoc2 = dumpAndParse(dumper, *xMetaFile);
2991 // no crossing out and vertical redlines
2992 assertXPath(pXmlDoc2, "/metafile/push/push/push/line", 0);
2995 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf142196)
2997 createSwDoc("tdf142196.fodt");
2998 SwDoc* pDoc = getSwDoc();
3000 //turn on red-lining and show changes
3001 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
3002 | RedlineFlags::ShowInsert);
3003 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3004 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
3005 CPPUNIT_ASSERT_MESSAGE(
3006 "redlines should be visible",
3007 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
3009 // Dump the rendering of the first page as an XML file.
3010 SwDocShell* pShell = pDoc->GetDocShell();
3011 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
3012 MetafileXmlDump dumper;
3014 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
3015 CPPUNIT_ASSERT(pXmlDoc);
3017 // This was 1 (missing crossing out of the deleted image)
3018 // (2 lines = crossing out of the deleted image + 1 line for the
3019 // vertical "changed line" indicator before the paragraph line)
3020 assertXPath(pXmlDoc, "//line", 3);
3022 // check line color
3023 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/linecolor", 1);
3024 // tdf#142128 This was NON_PRINTING_CHARACTER_COLOR (#268bd2)
3025 assertXPath(
3026 pXmlDoc,
3027 "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/linecolor[@color='#268bd2']", 0);
3029 // reject deletion of the image
3030 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
3031 rIDRA.AcceptAllRedline(false);
3033 xMetaFile = pShell->GetPreviewMetaFile();
3034 xmlDocUniquePtr pXmlDoc2 = dumpAndParse(dumper, *xMetaFile);
3036 // no crossing out and vertical "changed line" indicator
3037 assertXPath(pXmlDoc2, "//line", 0);
3040 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf142700)
3042 createSwDoc("tdf142700.fodt");
3043 SwDoc* pDoc = getSwDoc();
3045 //turn on red-lining and show changes
3046 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
3047 | RedlineFlags::ShowInsert);
3048 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3049 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
3050 CPPUNIT_ASSERT_MESSAGE(
3051 "redlines should be visible",
3052 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
3054 // Dump the rendering of the first page as an XML file.
3055 SwDocShell* pShell = pDoc->GetDocShell();
3056 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
3057 MetafileXmlDump dumper;
3059 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
3060 CPPUNIT_ASSERT(pXmlDoc);
3062 // (2 lines = crossing out of the deleted image + 1 line for the
3063 // vertical "changed line" indicator before the paragraph line)
3064 assertXPath(pXmlDoc, "//line", 3);
3066 // check line color
3067 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/linecolor", 1);
3068 // tdf#142128 This was NON_PRINTING_CHARACTER_COLOR (#268bd2)
3069 assertXPath(
3070 pXmlDoc,
3071 "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/linecolor[@color='#268bd2']", 0);
3073 // reject deletion of the image
3074 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
3075 rIDRA.AcceptAllRedline(false);
3077 xMetaFile = pShell->GetPreviewMetaFile();
3078 xmlDocUniquePtr pXmlDoc2 = dumpAndParse(dumper, *xMetaFile);
3080 // no crossing out and vertical "changed line" indicator
3081 // This was 2 (not removed strikethrough)
3082 assertXPath(pXmlDoc2, "//line", 0);
3085 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf139120)
3087 createSwDoc("tdf54819.fodt");
3088 SwDoc* pDoc = getSwDoc();
3089 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
3091 // switch on "Show changes in margin" mode
3092 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
3094 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
3095 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3097 // turn on red-lining and show changes
3098 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
3099 | RedlineFlags::ShowDelete);
3100 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3101 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
3102 CPPUNIT_ASSERT_MESSAGE(
3103 "redlines should be visible",
3104 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
3106 // delete paragraph break
3107 dispatchCommand(mxComponent, ".uno:GotoEndOfPara", {});
3108 for (int i = 0; i < 6; ++i)
3110 dispatchCommand(mxComponent, ".uno:Delete", {});
3113 CPPUNIT_ASSERT_EQUAL(OUString("Lorem ipsum sit amet."), pTextDoc->getText()->getString());
3115 for (int i = 0; i < 6; ++i)
3117 dispatchCommand(mxComponent, ".uno:Undo", {});
3120 CPPUNIT_ASSERT_EQUAL(OUString("Lorem ipsum"), getParagraph(1)->getString());
3121 CPPUNIT_ASSERT_EQUAL(OUString("dolor sit amet."), getParagraph(2)->getString());
3123 // Dump the rendering of the first page as an XML file.
3124 SwDocShell* pShell = pDoc->GetDocShell();
3125 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
3126 MetafileXmlDump dumper;
3127 xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
3128 CPPUNIT_ASSERT(pXmlDoc);
3130 // This was the 3, containing the text "$2" instead of nothing
3131 assertXPath(pXmlDoc, "/metafile/push/push/push/textarray", 2);
3133 // switch off "Show changes in margin" mode
3134 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
3135 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3138 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testJoinParaChangesInMargin)
3140 createSwDoc("tdf54819.fodt");
3141 SwDoc* pDoc = getSwDoc();
3143 // switch on "Show changes in margin" mode
3144 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
3146 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
3147 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3149 // turn on red-lining and show changes
3150 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
3151 | RedlineFlags::ShowDelete);
3152 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3153 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
3154 CPPUNIT_ASSERT_MESSAGE(
3155 "redlines should be visible",
3156 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
3158 // delete a character and the paragraph break at the end of the paragraph
3159 dispatchCommand(mxComponent, ".uno:GotoEndOfPara", {});
3160 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
3161 dispatchCommand(mxComponent, ".uno:Delete", {});
3162 dispatchCommand(mxComponent, ".uno:Delete", {});
3163 CPPUNIT_ASSERT_EQUAL(OUString("Lorem ipsudolor sit amet."), getParagraph(1)->getString());
3165 // Undo
3166 dispatchCommand(mxComponent, ".uno:Undo", {});
3167 // this would crash due to bad redline range
3168 dispatchCommand(mxComponent, ".uno:Undo", {});
3169 CPPUNIT_ASSERT_EQUAL(OUString("Lorem ipsum"), getParagraph(1)->getString());
3171 // switch off "Show changes in margin" mode
3172 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
3173 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3176 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf140757)
3178 createSwDoc("tdf54819.fodt");
3179 SwDoc* pDoc = getSwDoc();
3181 // switch on "Show changes in margin" mode
3182 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
3184 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
3185 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3187 // turn on red-lining and show changes
3188 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert
3189 | RedlineFlags::ShowDelete);
3190 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3191 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
3192 CPPUNIT_ASSERT_MESSAGE(
3193 "redlines should be visible",
3194 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
3196 // delete a character in the first paragraph, and another character in the second one
3197 dispatchCommand(mxComponent, ".uno:Delete", {});
3198 pWrtShell->Down(/*bSelect=*/false);
3199 dispatchCommand(mxComponent, ".uno:Delete", {});
3201 CPPUNIT_ASSERT_EQUAL(OUString("orem ipsum"), getParagraph(1)->getString());
3202 CPPUNIT_ASSERT_EQUAL(OUString("olor sit amet."), getParagraph(2)->getString());
3204 // accept all changes
3205 IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
3206 rIDRA.AcceptAllRedline(/*bAccept=*/true);
3208 CPPUNIT_ASSERT_EQUAL(OUString("orem ipsum"), getParagraph(1)->getString());
3209 CPPUNIT_ASSERT_EQUAL(OUString("olor sit amet."), getParagraph(2)->getString());
3211 // This crashed
3212 dispatchCommand(mxComponent, ".uno:Undo", {});
3214 // Check result of Undo
3215 rIDRA.AcceptAllRedline(/*bAccept=*/false);
3216 CPPUNIT_ASSERT_EQUAL(OUString("Lorem ipsum"), getParagraph(1)->getString());
3217 CPPUNIT_ASSERT_EQUAL(OUString("dolor sit amet."), getParagraph(2)->getString());
3219 // switch off "Show changes in margin" mode
3220 dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
3221 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
3224 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testConditionalHiddenSectionIssue)
3226 // tdf#54703
3227 // When exporting the bug document as PDF, the conditional hidden
3228 // sections became visible in the PDF and in the document.
3230 std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
3231 if (!pPDFium)
3232 return;
3234 createSwDoc("HiddenSection.odt");
3235 SwDoc* pDoc = getSwDoc();
3237 // Check section conditional hidden status - all should be hidden (IsCondHidden == true)
3238 for (SwNodeOffset i(0); i < pDoc->GetNodes().Count(); ++i)
3240 if (SwSectionNode const* const pNode = pDoc->GetNodes()[i]->GetSectionNode())
3242 CPPUNIT_ASSERT_EQUAL(true, pNode->GetSection().IsCondHidden());
3246 // PDF export
3247 save("writer_pdf_Export");
3249 auto pPdfDocument = parsePDFExport();
3250 auto pPdfPage = pPdfDocument->openPage(0);
3251 CPPUNIT_ASSERT(pPdfPage);
3253 // No PDF object should be present in the page - sections remained hidden
3254 CPPUNIT_ASSERT_EQUAL(0, pPdfPage->getObjectCount());
3256 // Check section conditional hidden status - all should remained hidden (IsCondHidden == true)
3257 for (SwNodeOffset i(0); i < pDoc->GetNodes().Count(); ++i)
3259 if (SwSectionNode const* const pNode = pDoc->GetNodes()[i]->GetSectionNode())
3261 CPPUNIT_ASSERT_EQUAL(true, pNode->GetSection().IsCondHidden());
3266 CPPUNIT_PLUGIN_IMPLEMENT();
3268 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */