1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <swmodeltestbase.hxx>
12 #include <boost/property_tree/json_parser.hpp>
14 #include <com/sun/star/awt/FontSlant.hpp>
15 #include <com/sun/star/awt/FontUnderline.hpp>
16 #include <com/sun/star/awt/FontWeight.hpp>
17 #include <com/sun/star/chart/XChartDocument.hpp>
18 #include <com/sun/star/chart2/XChartDocument.hpp>
19 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
20 #include <com/sun/star/view/XSelectionSupplier.hpp>
21 #include <com/sun/star/text/XTextTable.hpp>
22 #include <comphelper/propertysequence.hxx>
23 #include <comphelper/propertyvalue.hxx>
24 #include <comphelper/configuration.hxx>
25 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
26 #include <vcl/scheduler.hxx>
27 #include <vcl/settings.hxx>
29 #include <swdtflvr.hxx>
31 #include <IDocumentRedlineAccess.hxx>
33 #include <fmtanchr.hxx>
34 #include <UndoManager.hxx>
35 #include <sortedobjs.hxx>
36 #include <xmloff/odffields.hxx>
37 #include <sfx2/viewfrm.hxx>
38 #include <sfx2/dispatch.hxx>
39 #include <comphelper/lok.hxx>
44 #include <AnnotationWin.hxx>
45 #include <PostItMgr.hxx>
46 #include <fmtcntnt.hxx>
47 #include <frameformats.hxx>
48 #include <shellio.hxx>
49 #include <editeng/fontitem.hxx>
50 #include <tools/json_writer.hxx>
51 #include <unotxdoc.hxx>
52 #include <IDocumentLayoutAccess.hxx>
53 #include <rootfrm.hxx>
54 #include <com/sun/star/packages/zip/ZipFileAccess.hpp>
55 #include <redline.hxx>
57 /// Second set of tests asserting the behavior of Writer user interface shells.
58 class SwUiWriterTest5
: public SwModelTestBase
62 : SwModelTestBase(u
"/sw/qa/extras/uiwriter/data/"_ustr
)
67 AllSettings m_aSavedSettings
;
70 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf139127
)
72 createSwDoc("tdf139127.fodt");
73 SwDoc
* pDoc
= getSwDoc();
75 // switch on "Show changes in margin" mode
76 dispatchCommand(mxComponent
, u
".uno:ShowChangesInMargin"_ustr
, {});
78 SwWrtShell
* const pWrtShell
= getSwDocShell()->GetWrtShell();
79 CPPUNIT_ASSERT(pWrtShell
->GetViewOptions()->IsShowChangesInMargin());
81 // turn on red-lining and show changes
82 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowInsert
83 | RedlineFlags::ShowDelete
);
84 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
85 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
86 CPPUNIT_ASSERT_MESSAGE(
87 "redlines should be visible",
88 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
91 CPPUNIT_ASSERT_EQUAL(2, getPages());
93 // delete the last two characters with a page break at the end of the document
94 dispatchCommand(mxComponent
, u
".uno:GoToEndOfDoc"_ustr
, {});
95 dispatchCommand(mxComponent
, u
".uno:SwBackspace"_ustr
, {});
96 dispatchCommand(mxComponent
, u
".uno:SwBackspace"_ustr
, {});
97 CPPUNIT_ASSERT_EQUAL(1, getPages());
98 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
99 CPPUNIT_ASSERT_EQUAL(u
"First page"_ustr
, xTextDocument
->getText()->getString());
102 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
103 // this would crash due to bad redline range
104 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
105 CPPUNIT_ASSERT_EQUAL(2, getPages());
106 CPPUNIT_ASSERT_EQUAL(u
"First page"_ustr
, getParagraph(1)->getString());
107 CPPUNIT_ASSERT_EQUAL(u
"B"_ustr
, getParagraph(2)->getString());
109 // switch off "Show changes in margin" mode
110 dispatchCommand(mxComponent
, u
".uno:ShowChangesInMargin"_ustr
, {});
111 CPPUNIT_ASSERT(!pWrtShell
->GetViewOptions()->IsShowChangesInMargin());
114 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf138479
)
117 SwDoc
* const pDoc
= getSwDoc();
119 SwWrtShell
* const pWrtShell
= getSwDocShell()->GetWrtShell();
121 pWrtShell
->Insert(u
"Lorem"_ustr
);
122 CPPUNIT_ASSERT_EQUAL(u
"Lorem"_ustr
, getParagraph(1)->getString());
124 //turn on red-lining and show changes
125 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
126 | RedlineFlags::ShowInsert
);
127 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
);
128 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
129 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
130 CPPUNIT_ASSERT_MESSAGE("redlines shouldn't be visible",
131 !IDocumentRedlineAccess::IsShowChanges(
132 pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
134 // switch on "Show changes in margin" mode
135 dispatchCommand(mxComponent
, u
".uno:ShowChangesInMargin"_ustr
, {});
137 // delete "r" in "Lorem"
138 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/false, 3, /*bBasicCall=*/false);
139 dispatchCommand(mxComponent
, u
".uno:Delete"_ustr
, {});
140 CPPUNIT_ASSERT_EQUAL(u
"Loem"_ustr
, getParagraph(1)->getString());
142 // delete "oe" in "Loem"
143 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
144 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 2, /*bBasicCall=*/false);
145 dispatchCommand(mxComponent
, u
".uno:Delete"_ustr
, {});
146 CPPUNIT_ASSERT_EQUAL(u
"Lm"_ustr
, getParagraph(1)->getString());
148 // test embedded Undo in ChangesInMargin mode
149 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
150 CPPUNIT_ASSERT_EQUAL(u
"Loem"_ustr
, getParagraph(1)->getString());
152 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
153 CPPUNIT_ASSERT_EQUAL(u
"Lorem"_ustr
, getParagraph(1)->getString());
155 // this would crash due to bad redline range
156 for (int i
= 0; i
< 5; ++i
)
157 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
159 // switch off "Show changes in margin" mode
160 dispatchCommand(mxComponent
, u
".uno:ShowChangesInMargin"_ustr
, {});
161 CPPUNIT_ASSERT(!pWrtShell
->GetViewOptions()->IsShowChangesInMargin());
164 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf138666
)
166 createSwDoc("tdf39721.fodt");
167 SwDoc
* pDoc
= getSwDoc();
169 //turn on red-lining and show changes
170 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
171 | RedlineFlags::ShowInsert
);
172 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
173 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
174 CPPUNIT_ASSERT_MESSAGE(
175 "redlines should be visible",
176 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
178 // show deletions inline
179 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum"_ustr
, getParagraph(1)->getString());
180 CPPUNIT_ASSERT_EQUAL(u
"dolor sit"_ustr
, getParagraph(2)->getString());
182 // switch on "Show changes in margin" mode
183 dispatchCommand(mxComponent
, u
".uno:ShowChangesInMargin"_ustr
, {});
185 // show deletions in margin
186 CPPUNIT_ASSERT_EQUAL(u
"Loremm"_ustr
, getParagraph(1)->getString());
187 CPPUNIT_ASSERT_EQUAL(u
"dolsit"_ustr
, getParagraph(2)->getString());
189 // switch off "Show changes in margin" mode
190 dispatchCommand(mxComponent
, u
".uno:ShowChangesInMargin"_ustr
, {});
192 // show deletions inline again
193 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum"_ustr
, getParagraph(1)->getString());
194 CPPUNIT_ASSERT_EQUAL(u
"dolor sit"_ustr
, getParagraph(2)->getString());
197 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf140982
)
199 createSwDoc("tdf115815.odt");
200 SwDoc
* pDoc
= getSwDoc();
202 //turn on red-lining and show changes
203 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
204 | RedlineFlags::ShowInsert
);
205 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
206 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
207 CPPUNIT_ASSERT_MESSAGE(
208 "redlines should be visible",
209 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
211 // show deletions inline
212 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum dolor sit amet..."_ustr
, getParagraph(1)->getString());
214 // switch on "Show changes in margin" mode
215 dispatchCommand(mxComponent
, u
".uno:ShowChangesInMargin"_ustr
, {});
217 // show deletions in margin
218 CPPUNIT_ASSERT_EQUAL(u
"Lorem amet..."_ustr
, getParagraph(1)->getString());
220 // switch off "Show changes in margin" mode
221 dispatchCommand(mxComponent
, u
".uno:ShowChangesInMargin"_ustr
, {});
223 // show deletions inline again
224 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum dolor sit amet..."_ustr
, getParagraph(1)->getString());
226 // Save it and load it back.
227 saveAndReload(u
"writer8"_ustr
);
229 // Test comment range feature on tracked deletion.
230 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
231 uno::Reference
<container::XEnumerationAccess
> xParaEnumAccess(xTextDocument
->getText(),
233 uno::Reference
<container::XEnumeration
> xParaEnum
= xParaEnumAccess
->createEnumeration();
234 uno::Reference
<container::XEnumerationAccess
> xRunEnumAccess(xParaEnum
->nextElement(),
236 uno::Reference
<container::XEnumeration
> xRunEnum
= xRunEnumAccess
->createEnumeration();
237 bool bAnnotationStart
= false;
238 bool bBeforeAnnotation
= true;
239 OUString sTextBeforeAnnotation
;
240 while (xRunEnum
->hasMoreElements())
242 uno::Reference
<beans::XPropertySet
> xPropertySet(xRunEnum
->nextElement(), uno::UNO_QUERY
);
243 OUString aType
= getProperty
<OUString
>(xPropertySet
, u
"TextPortionType"_ustr
);
244 // there is no AnnotationEnd with preceding AnnotationStart,
245 // i.e. annotation with lost range
246 CPPUNIT_ASSERT(aType
!= "AnnotationEnd" || !bAnnotationStart
);
248 bAnnotationStart
= (aType
== "Annotation");
250 // collect paragraph text before the first annotation
251 if (bBeforeAnnotation
)
253 if (bAnnotationStart
)
254 bBeforeAnnotation
= false;
255 else if (aType
== "Text")
257 uno::Reference
<text::XTextRange
> xRun(xPropertySet
, uno::UNO_QUERY
);
258 sTextBeforeAnnotation
+= xRun
->getString();
263 // This was "Lorem ipsum" (collapsed annotation range)
264 CPPUNIT_ASSERT_EQUAL(u
"Lorem "_ustr
, sTextBeforeAnnotation
);
267 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf126206
)
269 createSwDoc("tdf126206.docx");
271 // normal text (it was bold)
272 auto xText
= getParagraph(1)->getText();
273 CPPUNIT_ASSERT(xText
.is());
275 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 4)));
276 CPPUNIT_ASSERT(xCursor
.is());
277 CPPUNIT_ASSERT_EQUAL(u
"ipsum"_ustr
, xCursor
->getString());
278 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL
,
279 getProperty
<float>(xCursor
, u
"CharWeight"_ustr
));
282 // reject tracked changes
283 dispatchCommand(mxComponent
, u
".uno:RejectAllTrackedChanges"_ustr
, {});
286 xText
= getParagraph(1)->getText();
287 CPPUNIT_ASSERT(xText
.is());
289 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 3)));
290 CPPUNIT_ASSERT(xCursor
.is());
291 CPPUNIT_ASSERT_EQUAL(u
"ipsum"_ustr
, xCursor
->getString());
292 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD
,
293 getProperty
<float>(xCursor
, u
"CharWeight"_ustr
));
297 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf50447
)
299 createSwDoc("tdf126206.docx");
301 SwWrtShell
* const pWrtShell
= getSwDocShell()->GetWrtShell();
304 auto xText
= getParagraph(1)->getText();
305 CPPUNIT_ASSERT(xText
.is());
307 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 1)));
308 CPPUNIT_ASSERT(xCursor
.is());
309 CPPUNIT_ASSERT_EQUAL(u
"Lorem "_ustr
, xCursor
->getString());
310 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD
,
311 getProperty
<float>(xCursor
, u
"CharWeight"_ustr
));
314 // remove bold formatting with change tracking
315 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 6, /*bBasicCall=*/false);
316 dispatchCommand(mxComponent
, u
".uno:Bold"_ustr
, {});
318 xText
= getParagraph(1)->getText();
319 CPPUNIT_ASSERT(xText
.is());
321 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 2)));
322 CPPUNIT_ASSERT(xCursor
.is());
323 CPPUNIT_ASSERT_EQUAL(u
"Lorem "_ustr
, xCursor
->getString());
324 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL
,
325 getProperty
<float>(xCursor
, u
"CharWeight"_ustr
));
328 // reject tracked changes
329 dispatchCommand(mxComponent
, u
".uno:RejectAllTrackedChanges"_ustr
, {});
332 xText
= getParagraph(1)->getText();
333 CPPUNIT_ASSERT(xText
.is());
335 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 1)));
336 CPPUNIT_ASSERT(xCursor
.is());
337 CPPUNIT_ASSERT_EQUAL(u
"Lorem "_ustr
, xCursor
->getString());
339 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD
,
340 getProperty
<float>(xCursor
, u
"CharWeight"_ustr
));
344 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf143918
)
346 createSwDoc("tdf126206.docx");
348 SwWrtShell
* const pWrtShell
= getSwDocShell()->GetWrtShell();
351 auto xText
= getParagraph(1)->getText();
352 CPPUNIT_ASSERT(xText
.is());
354 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 1)));
355 CPPUNIT_ASSERT(xCursor
.is());
356 CPPUNIT_ASSERT_EQUAL(u
"Lorem "_ustr
, xCursor
->getString());
357 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD
,
358 getProperty
<float>(xCursor
, u
"CharWeight"_ustr
));
361 // remove bold formatting with change tracking and after that, apply underline, too
362 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 6, /*bBasicCall=*/false);
363 dispatchCommand(mxComponent
, u
".uno:Bold"_ustr
, {});
364 dispatchCommand(mxComponent
, u
".uno:Underline"_ustr
, {});
366 xText
= getParagraph(1)->getText();
367 CPPUNIT_ASSERT(xText
.is());
369 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 2)));
370 CPPUNIT_ASSERT(xCursor
.is());
371 CPPUNIT_ASSERT_EQUAL(u
"Lorem "_ustr
, xCursor
->getString());
372 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL
,
373 getProperty
<float>(xCursor
, u
"CharWeight"_ustr
));
376 // reject tracked changes
377 dispatchCommand(mxComponent
, u
".uno:RejectAllTrackedChanges"_ustr
, {});
380 xText
= getParagraph(1)->getText();
381 CPPUNIT_ASSERT(xText
.is());
383 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 1)));
384 CPPUNIT_ASSERT(xCursor
.is());
385 CPPUNIT_ASSERT_EQUAL(u
"Lorem "_ustr
, xCursor
->getString());
386 // This was NORMAL (only underlining was removed)
387 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD
,
388 getProperty
<float>(xCursor
, u
"CharWeight"_ustr
));
392 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf143938
)
394 createSwDoc("tdf54819.fodt");
395 SwDoc
* pDoc
= getSwDoc();
397 SwWrtShell
* const pWrtShell
= getSwDocShell()->GetWrtShell();
399 // select first paragraph, add underline without change tracking
400 pWrtShell
->EndPara(/*bSelect=*/true);
401 dispatchCommand(mxComponent
, u
".uno:Underline"_ustr
, {});
403 auto xText
= getParagraph(1)->getText();
404 CPPUNIT_ASSERT(xText
.is());
406 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 1)));
407 CPPUNIT_ASSERT(xCursor
.is());
408 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum"_ustr
, xCursor
->getString());
409 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::SINGLE
),
410 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
411 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE
,
412 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
415 // turn on red-lining and show changes
416 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
417 | RedlineFlags::ShowInsert
);
418 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
419 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
420 CPPUNIT_ASSERT_MESSAGE(
421 "redlines should be visible",
422 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
424 // apply italic with change tracking
425 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 6, /*bBasicCall=*/false);
426 dispatchCommand(mxComponent
, u
".uno:Italic"_ustr
, {});
428 xText
= getParagraph(1)->getText();
429 CPPUNIT_ASSERT(xText
.is());
431 // (first empty run is associated to the redline)
432 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 2)));
433 CPPUNIT_ASSERT(xCursor
.is());
434 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum"_ustr
, xCursor
->getString());
435 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::SINGLE
),
436 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
437 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC
,
438 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
441 // reject tracked changes
442 dispatchCommand(mxComponent
, u
".uno:RejectAllTrackedChanges"_ustr
, {});
444 // no italic, but still underline direct formatting
445 xText
= getParagraph(1)->getText();
446 CPPUNIT_ASSERT(xText
.is());
448 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 1)));
449 CPPUNIT_ASSERT(xCursor
.is());
450 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum"_ustr
, xCursor
->getString());
451 // This wasn't underlined (lost direct formatting)
452 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::SINGLE
),
453 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
454 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE
,
455 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
459 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf143939
)
461 createSwDoc("tdf126206.docx");
463 SwWrtShell
* const pWrtShell
= getSwDocShell()->GetWrtShell();
466 auto xText
= getParagraph(1)->getText();
467 CPPUNIT_ASSERT(xText
.is());
469 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 1)));
470 CPPUNIT_ASSERT(xCursor
.is());
471 CPPUNIT_ASSERT_EQUAL(u
"Lorem "_ustr
, xCursor
->getString());
472 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD
,
473 getProperty
<float>(xCursor
, u
"CharWeight"_ustr
));
476 // positionate the text cursor inside the first word
477 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
478 // remove bold formatting with change tracking without selection
479 dispatchCommand(mxComponent
, u
".uno:Bold"_ustr
, {});
481 xText
= getParagraph(1)->getText();
482 CPPUNIT_ASSERT(xText
.is());
484 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 2)));
485 CPPUNIT_ASSERT(xCursor
.is());
486 CPPUNIT_ASSERT_EQUAL(u
"Lorem"_ustr
, xCursor
->getString());
487 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL
,
488 getProperty
<float>(xCursor
, u
"CharWeight"_ustr
));
491 // reject tracked changes
492 dispatchCommand(mxComponent
, u
".uno:RejectAllTrackedChanges"_ustr
, {});
495 xText
= getParagraph(1)->getText();
496 CPPUNIT_ASSERT(xText
.is());
498 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 1)));
499 CPPUNIT_ASSERT(xCursor
.is());
500 CPPUNIT_ASSERT_EQUAL(u
"Lorem"_ustr
, xCursor
->getString());
502 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD
,
503 getProperty
<float>(xCursor
, u
"CharWeight"_ustr
));
507 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf50447_keep_hints
)
509 createSwDoc("tdf50447.fodt");
510 SwDoc
* pDoc
= getSwDoc();
512 // first paragraph (_Lorem_ /ipsum/)
514 auto xText
= getParagraph(1)->getText();
515 CPPUNIT_ASSERT(xText
.is());
517 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 1)));
518 CPPUNIT_ASSERT(xCursor
.is());
519 CPPUNIT_ASSERT_EQUAL(u
"Lorem"_ustr
, xCursor
->getString());
520 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::SINGLE
),
521 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
522 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE
,
523 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
525 xCursor
= xText
->createTextCursorByRange(getRun(getParagraph(1), 2));
526 CPPUNIT_ASSERT(xCursor
.is());
527 CPPUNIT_ASSERT_EQUAL(u
" "_ustr
, xCursor
->getString());
528 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::NONE
),
529 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
530 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE
,
531 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
533 xCursor
= xText
->createTextCursorByRange(getRun(getParagraph(1), 3));
534 CPPUNIT_ASSERT(xCursor
.is());
535 CPPUNIT_ASSERT_EQUAL(u
"ipsum"_ustr
, xCursor
->getString());
536 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::NONE
),
537 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
538 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC
,
539 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
542 // second paragraph (_dolor_ sit /amet/.)
544 xText
= getParagraph(2)->getText();
545 CPPUNIT_ASSERT(xText
.is());
547 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(2), 1)));
548 CPPUNIT_ASSERT(xCursor
.is());
549 CPPUNIT_ASSERT_EQUAL(u
"dolor"_ustr
, xCursor
->getString());
550 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::SINGLE
),
551 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
552 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE
,
553 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
555 xCursor
= xText
->createTextCursorByRange(getRun(getParagraph(2), 2));
556 CPPUNIT_ASSERT(xCursor
.is());
557 CPPUNIT_ASSERT_EQUAL(u
" sit "_ustr
, xCursor
->getString());
558 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::NONE
),
559 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
560 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE
,
561 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
563 xCursor
= xText
->createTextCursorByRange(getRun(getParagraph(2), 3));
564 CPPUNIT_ASSERT(xCursor
.is());
565 CPPUNIT_ASSERT_EQUAL(u
"amet"_ustr
, xCursor
->getString());
566 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::NONE
),
567 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
568 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC
,
569 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
572 // turn on red-lining and show changes
573 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
574 | RedlineFlags::ShowInsert
);
575 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
576 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
577 CPPUNIT_ASSERT_MESSAGE(
578 "redlines should be visible",
579 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
581 // modify character formatting of the all the text
583 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
584 dispatchCommand(mxComponent
, u
".uno:SuperScript"_ustr
, {});
586 // multiple format redlines for the multiple hints
588 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
589 CPPUNIT_ASSERT(pEditShell
);
591 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(7), pEditShell
->GetRedlineCount());
593 // reject tracked changes
595 dispatchCommand(mxComponent
, u
".uno:RejectAllTrackedChanges"_ustr
, {});
597 // all hints and text portions between them got back the original formatting
599 xText
= getParagraph(1)->getText();
600 CPPUNIT_ASSERT(xText
.is());
602 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(1), 1)));
603 CPPUNIT_ASSERT(xCursor
.is());
604 CPPUNIT_ASSERT_EQUAL(u
"Lorem"_ustr
, xCursor
->getString());
606 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::SINGLE
),
607 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
608 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE
,
609 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
611 xCursor
= xText
->createTextCursorByRange(getRun(getParagraph(1), 2));
612 CPPUNIT_ASSERT(xCursor
.is());
613 CPPUNIT_ASSERT_EQUAL(u
" "_ustr
, xCursor
->getString());
614 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::NONE
),
615 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
616 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE
,
617 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
619 xCursor
= xText
->createTextCursorByRange(getRun(getParagraph(1), 3));
620 CPPUNIT_ASSERT(xCursor
.is());
621 CPPUNIT_ASSERT_EQUAL(u
"ipsum"_ustr
, xCursor
->getString());
622 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::NONE
),
623 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
625 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC
,
626 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
629 // second paragraph (_dolor_ sit /amet/.)
631 xText
= getParagraph(2)->getText();
632 CPPUNIT_ASSERT(xText
.is());
634 auto xCursor(xText
->createTextCursorByRange(getRun(getParagraph(2), 1)));
635 CPPUNIT_ASSERT(xCursor
.is());
636 CPPUNIT_ASSERT_EQUAL(u
"dolor"_ustr
, xCursor
->getString());
638 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::SINGLE
),
639 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
640 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE
,
641 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
643 xCursor
= xText
->createTextCursorByRange(getRun(getParagraph(2), 2));
644 CPPUNIT_ASSERT(xCursor
.is());
645 CPPUNIT_ASSERT_EQUAL(u
" sit "_ustr
, xCursor
->getString());
646 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::NONE
),
647 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
648 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE
,
649 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
651 xCursor
= xText
->createTextCursorByRange(getRun(getParagraph(2), 3));
652 CPPUNIT_ASSERT(xCursor
.is());
653 CPPUNIT_ASSERT_EQUAL(u
"amet"_ustr
, xCursor
->getString());
654 CPPUNIT_ASSERT_EQUAL(sal_Int16(awt::FontUnderline::NONE
),
655 getProperty
<sal_Int16
>(xCursor
, u
"CharUnderline"_ustr
));
657 CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC
,
658 getProperty
<awt::FontSlant
>(xCursor
, u
"CharPosture"_ustr
));
662 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf144272
)
664 createSwDoc("tdf50447.fodt");
665 SwDoc
* pDoc
= getSwDoc();
667 SwWrtShell
* const pWrtShell
= getSwDocShell()->GetWrtShell();
669 // turn on red-lining and show changes
670 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
671 | RedlineFlags::ShowInsert
);
672 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
673 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
674 CPPUNIT_ASSERT_MESSAGE(
675 "redlines should be visible",
676 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
678 // paragraph style of the first paragraph: Heading 1, second paragraph: Standard
680 CPPUNIT_ASSERT_EQUAL(u
"Heading 1"_ustr
,
681 getProperty
<OUString
>(getParagraph(1), u
"ParaStyleName"_ustr
));
682 CPPUNIT_ASSERT_EQUAL(u
"Standard"_ustr
,
683 getProperty
<OUString
>(getParagraph(2), u
"ParaStyleName"_ustr
));
685 // modify with track changes: Standard and Heading 2
687 uno::Sequence
<beans::PropertyValue
> aPropertyValues
= comphelper::InitPropertySequence({
688 { "Style", uno::Any(u
"Standard"_ustr
) },
689 { "FamilyName", uno::Any(u
"ParagraphStyles"_ustr
) },
691 dispatchCommand(mxComponent
, u
".uno:StyleApply"_ustr
, aPropertyValues
);
692 pWrtShell
->Down(/*bSelect=*/false);
693 aPropertyValues
= comphelper::InitPropertySequence({
694 { "Style", uno::Any(u
"Heading 2"_ustr
) },
695 { "FamilyName", uno::Any(u
"ParagraphStyles"_ustr
) },
697 dispatchCommand(mxComponent
, u
".uno:StyleApply"_ustr
, aPropertyValues
);
699 CPPUNIT_ASSERT_EQUAL(u
"Standard"_ustr
,
700 getProperty
<OUString
>(getParagraph(1), u
"ParaStyleName"_ustr
));
701 CPPUNIT_ASSERT_EQUAL(u
"Heading 2"_ustr
,
702 getProperty
<OUString
>(getParagraph(2), u
"ParaStyleName"_ustr
));
704 // reject tracked changes
705 dispatchCommand(mxComponent
, u
".uno:RejectAllTrackedChanges"_ustr
, {});
707 // This was Standard (missing reject)
708 CPPUNIT_ASSERT_EQUAL(u
"Heading 1"_ustr
,
709 getProperty
<OUString
>(getParagraph(1), u
"ParaStyleName"_ustr
));
710 // This was Heading 2 (missing reject)
711 CPPUNIT_ASSERT_EQUAL(u
"Standard"_ustr
,
712 getProperty
<OUString
>(getParagraph(2), u
"ParaStyleName"_ustr
));
715 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf101873
)
718 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
719 CPPUNIT_ASSERT(pWrtShell
);
721 // Insert some content.
722 pWrtShell
->Insert(u
"something"_ustr
);
724 // Search for something which does not exist, twice.
725 uno::Sequence
<beans::PropertyValue
> aFirst(comphelper::InitPropertySequence({
726 { "SearchItem.SearchString", uno::Any(u
"fig"_ustr
) },
727 { "SearchItem.Backward", uno::Any(false) },
729 dispatchCommand(mxComponent
, u
".uno:ExecuteSearch"_ustr
, aFirst
);
730 dispatchCommand(mxComponent
, u
".uno:ExecuteSearch"_ustr
, aFirst
);
732 uno::Sequence
<beans::PropertyValue
> aSecond(comphelper::InitPropertySequence({
733 { "SearchItem.SearchString", uno::Any(u
"something"_ustr
) },
734 { "SearchItem.Backward", uno::Any(false) },
736 dispatchCommand(mxComponent
, u
".uno:ExecuteSearch"_ustr
, aSecond
);
738 // Without the accompanying fix in place, this test would have failed with "Expected: something;
739 // Actual:", i.e. searching for "something" failed, even if it was inserted above.
740 SwShellCursor
* pShellCursor
= pWrtShell
->getShellCursor(false);
741 CPPUNIT_ASSERT_EQUAL(u
"something"_ustr
, pShellCursor
->GetText());
744 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTextFormFieldInsertion
)
747 SwDoc
* pDoc
= getSwDoc();
748 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
749 CPPUNIT_ASSERT(pMarkAccess
);
750 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
752 // Insert a text form field
753 dispatchCommand(mxComponent
, u
".uno:TextFormField"_ustr
, {});
754 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
756 // Check whether the fieldmark is created
757 auto aIter
= pMarkAccess
->getAllMarksBegin();
758 CPPUNIT_ASSERT(aIter
!= pMarkAccess
->getAllMarksEnd());
759 ::sw::mark::Fieldmark
* pFieldmark
= dynamic_cast<::sw::mark::Fieldmark
*>(*aIter
);
760 CPPUNIT_ASSERT(pFieldmark
);
761 CPPUNIT_ASSERT_EQUAL(ODF_FORMTEXT
, pFieldmark
->GetFieldname());
763 // The text form field has the placeholder text in it
764 uno::Reference
<text::XTextRange
> xPara
= getParagraph(1);
765 CPPUNIT_ASSERT_EQUAL(vEnSpaces
, xPara
->getString());
768 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
769 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
770 xPara
.set(getParagraph(1));
771 CPPUNIT_ASSERT(xPara
->getString().isEmpty());
774 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
775 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
776 xPara
.set(getParagraph(1));
777 CPPUNIT_ASSERT_EQUAL(vEnSpaces
, xPara
->getString());
780 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testCheckboxFormFieldInsertion
)
783 SwDoc
* pDoc
= getSwDoc();
785 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
786 CPPUNIT_ASSERT(pMarkAccess
);
787 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
789 // Insert a checkbox form field
790 dispatchCommand(mxComponent
, u
".uno:CheckBoxFormField"_ustr
, {});
791 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
793 // Check whether the fieldmark is created
794 auto aIter
= pMarkAccess
->getAllMarksBegin();
795 CPPUNIT_ASSERT(aIter
!= pMarkAccess
->getAllMarksEnd());
796 ::sw::mark::Fieldmark
* pFieldmark
= dynamic_cast<::sw::mark::Fieldmark
*>(*aIter
);
797 CPPUNIT_ASSERT(pFieldmark
);
798 CPPUNIT_ASSERT_EQUAL(ODF_FORMCHECKBOX
, pFieldmark
->GetFieldname());
799 // The checkbox is not checked by default
800 ::sw::mark::CheckboxFieldmark
* pCheckBox
801 = dynamic_cast<::sw::mark::CheckboxFieldmark
*>(pFieldmark
);
802 CPPUNIT_ASSERT(pCheckBox
);
803 CPPUNIT_ASSERT(!pCheckBox
->IsChecked());
806 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
807 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
810 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
811 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
812 aIter
= pMarkAccess
->getAllMarksBegin();
813 CPPUNIT_ASSERT(aIter
!= pMarkAccess
->getAllMarksEnd());
814 pFieldmark
= dynamic_cast<::sw::mark::Fieldmark
*>(*aIter
);
815 CPPUNIT_ASSERT(pFieldmark
);
816 CPPUNIT_ASSERT_EQUAL(ODF_FORMCHECKBOX
, pFieldmark
->GetFieldname());
818 // tdf#147008 this would crash
819 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
820 pWrtShell
->StartOfSection(false);
821 pWrtShell
->SplitNode();
822 CPPUNIT_ASSERT_EQUAL(pFieldmark
->GetMarkPos().GetNodeIndex(),
823 pFieldmark
->GetOtherMarkPos().GetNodeIndex());
824 CPPUNIT_ASSERT_EQUAL(sal_Int32(pFieldmark
->GetMarkPos().GetContentIndex() + 1),
825 pFieldmark
->GetOtherMarkPos().GetContentIndex());
828 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testDropDownFormFieldInsertion
)
831 SwDoc
* pDoc
= getSwDoc();
833 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
834 CPPUNIT_ASSERT(pMarkAccess
);
835 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
837 // Insert a drop-down form field
838 dispatchCommand(mxComponent
, u
".uno:DropDownFormField"_ustr
, {});
839 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
841 // Check whether the fieldmark is created
842 auto aIter
= pMarkAccess
->getAllMarksBegin();
843 CPPUNIT_ASSERT(aIter
!= pMarkAccess
->getAllMarksEnd());
844 ::sw::mark::Fieldmark
* pFieldmark
= dynamic_cast<::sw::mark::Fieldmark
*>(*aIter
);
845 CPPUNIT_ASSERT(pFieldmark
);
846 CPPUNIT_ASSERT_EQUAL(ODF_FORMDROPDOWN
, pFieldmark
->GetFieldname());
847 // Check drop down field's parameters. By default these params are not set
848 const sw::mark::Fieldmark::parameter_map_t
* const pParameters
= pFieldmark
->GetParameters();
849 auto pListEntries
= pParameters
->find(ODF_FORMDROPDOWN_LISTENTRY
);
850 CPPUNIT_ASSERT(bool(pListEntries
== pParameters
->end()));
851 auto pResult
= pParameters
->find(ODF_FORMDROPDOWN_RESULT
);
852 CPPUNIT_ASSERT(bool(pResult
== pParameters
->end()));
855 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
856 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
859 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
860 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
861 aIter
= pMarkAccess
->getAllMarksBegin();
862 CPPUNIT_ASSERT(aIter
!= pMarkAccess
->getAllMarksEnd());
863 pFieldmark
= dynamic_cast<::sw::mark::Fieldmark
*>(*aIter
);
864 CPPUNIT_ASSERT(pFieldmark
);
865 CPPUNIT_ASSERT_EQUAL(ODF_FORMDROPDOWN
, pFieldmark
->GetFieldname());
868 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testMixedFormFieldInsertion
)
871 SwDoc
* pDoc
= getSwDoc();
873 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
874 CPPUNIT_ASSERT(pMarkAccess
);
875 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
878 dispatchCommand(mxComponent
, u
".uno:TextFormField"_ustr
, {});
879 dispatchCommand(mxComponent
, u
".uno:CheckBoxFormField"_ustr
, {});
880 dispatchCommand(mxComponent
, u
".uno:DropDownFormField"_ustr
, {});
881 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMarkAccess
->getAllMarksCount());
884 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
885 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
886 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
887 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
890 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
891 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
892 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
893 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMarkAccess
->getAllMarksCount());
896 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf147723
)
898 createSwDoc("tdf147723.docx");
899 SwDoc
* const pDoc
= getSwDoc();
901 IDocumentMarkAccess
& rIDMA(*pDoc
->getIDocumentMarkAccess());
902 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), rIDMA
.getAllMarksCount());
904 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
905 dispatchCommand(mxComponent
, u
".uno:Copy"_ustr
, {});
907 // Without the fix in place, this test would have crashed here
908 dispatchCommand(mxComponent
, u
".uno:Paste"_ustr
, {});
909 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), rIDMA
.getAllMarksCount());
910 dispatchCommand(mxComponent
, u
".uno:Paste"_ustr
, {});
911 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), rIDMA
.getAllMarksCount());
912 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
913 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), rIDMA
.getAllMarksCount());
914 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
915 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), rIDMA
.getAllMarksCount());
918 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf147006
)
920 createSwDoc("tdf147006.rtf");
921 SwDoc
* const pDoc
= getSwDoc();
923 IDocumentMarkAccess
& rIDMA(*pDoc
->getIDocumentMarkAccess());
924 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc
->GetFlyCount(FLYCNTTYPE_FRM
));
925 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc
->GetFlyCount(FLYCNTTYPE_GRF
));
926 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getAllMarksCount());
927 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getFieldmarksCount());
929 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
931 dispatchCommand(mxComponent
, u
".uno:Delete"_ustr
, {});
932 CPPUNIT_ASSERT_EQUAL(size_t(0), pDoc
->GetFlyCount(FLYCNTTYPE_FRM
));
933 CPPUNIT_ASSERT_EQUAL(size_t(0), pDoc
->GetFlyCount(FLYCNTTYPE_GRF
));
934 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rIDMA
.getAllMarksCount());
935 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
936 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc
->GetFlyCount(FLYCNTTYPE_FRM
));
937 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc
->GetFlyCount(FLYCNTTYPE_GRF
));
938 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getAllMarksCount());
939 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
940 CPPUNIT_ASSERT_EQUAL(size_t(0), pDoc
->GetFlyCount(FLYCNTTYPE_FRM
));
941 CPPUNIT_ASSERT_EQUAL(size_t(0), pDoc
->GetFlyCount(FLYCNTTYPE_GRF
));
942 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rIDMA
.getAllMarksCount());
943 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
944 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc
->GetFlyCount(FLYCNTTYPE_FRM
));
945 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc
->GetFlyCount(FLYCNTTYPE_GRF
));
946 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getAllMarksCount());
947 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
948 CPPUNIT_ASSERT_EQUAL(size_t(0), pDoc
->GetFlyCount(FLYCNTTYPE_FRM
));
949 CPPUNIT_ASSERT_EQUAL(size_t(0), pDoc
->GetFlyCount(FLYCNTTYPE_GRF
));
950 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rIDMA
.getAllMarksCount());
953 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testDocxAttributeTableExport
)
955 createSwDoc("floating-table-position.docx");
957 // get the table frame, set new values and dismiss the references
959 uno::Reference
<beans::XPropertySet
> xShape(getShape(1), uno::UNO_QUERY
);
961 // change the properties
963 xShape
->setPropertyValue(u
"VertOrientPosition"_ustr
,
964 uno::Any(static_cast<sal_Int32
>(8000)));
966 xShape
->setPropertyValue(u
"HoriOrientPosition"_ustr
,
967 uno::Any(static_cast<sal_Int32
>(5000)));
968 // 0 (frame) -> 8 (page print area)
969 xShape
->setPropertyValue(u
"VertOrientRelation"_ustr
, uno::Any(static_cast<sal_Int16
>(8)));
970 // 8 (page print area) -> 0 (frame)
971 xShape
->setPropertyValue(u
"HoriOrientRelation"_ustr
, uno::Any(static_cast<sal_Int16
>(0)));
974 saveAndReload(u
"Office Open XML Text"_ustr
);
976 uno::Reference
<beans::XPropertySet
> xShape(getShape(1), uno::UNO_QUERY
);
978 // test the new values
979 sal_Int32 nValue
= getProperty
<sal_Int32
>(xShape
, u
"VertOrientPosition"_ustr
);
980 CPPUNIT_ASSERT(sal_Int32(7999) <= nValue
);
981 CPPUNIT_ASSERT(nValue
<= sal_Int32(8001));
982 nValue
= getProperty
<sal_Int32
>(xShape
, u
"HoriOrientPosition"_ustr
);
983 CPPUNIT_ASSERT(sal_Int32(4999) <= nValue
);
984 CPPUNIT_ASSERT(nValue
<= sal_Int32(5001));
986 CPPUNIT_ASSERT_EQUAL(sal_Int16(8), getProperty
<sal_Int16
>(xShape
, u
"VertOrientRelation"_ustr
));
987 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty
<sal_Int16
>(xShape
, u
"HoriOrientRelation"_ustr
));
990 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf118699_redline_numbering
)
992 createSwDoc("tdf118699.docx");
993 SwDoc
* pDoc
= getSwDoc();
995 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
996 rIDRA
.AcceptAllRedline(true);
998 uno::Reference
<beans::XPropertySet
> xProps(getParagraph(2), uno::UNO_QUERY_THROW
);
999 CPPUNIT_ASSERT_MESSAGE("first paragraph after the first deletion: erroneous numbering",
1000 !xProps
->getPropertyValue(u
"NumberingRules"_ustr
).hasValue());
1002 CPPUNIT_ASSERT_MESSAGE("first paragraph after the second deletion: missing numbering",
1003 getProperty
<uno::Reference
<container::XIndexAccess
>>(
1004 getParagraph(5), u
"NumberingRules"_ustr
)
1008 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf125881_redline_list_level
)
1010 createSwDoc("tdf125881.docx");
1012 uno::Reference
<beans::XPropertySet
> xProps(getParagraph(8), uno::UNO_QUERY_THROW
);
1013 CPPUNIT_ASSERT_MESSAGE("deleted paragraph: erroneous numbering",
1014 !xProps
->getPropertyValue(u
"NumberingRules"_ustr
).hasValue());
1016 // deleted paragraph gets the numbering of the next paragraph
1017 uno::Reference
<beans::XPropertySet
> xProps2(getParagraph(9), uno::UNO_QUERY_THROW
);
1018 CPPUNIT_ASSERT_MESSAGE("first paragraph after the first deletion: missing numbering",
1019 xProps2
->getPropertyValue(u
"NumberingRules"_ustr
).hasValue());
1021 // check numbering level at deletion (1 instead of 0)
1022 CPPUNIT_ASSERT_EQUAL(sal_Int16(1),
1023 getProperty
<sal_Int16
>(getParagraph(9), u
"NumberingLevel"_ustr
));
1026 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf125916_redline_restart_numbering
)
1028 createSwDoc("tdf125916.docx");
1029 SwDoc
* pDoc
= getSwDoc();
1031 // moveFrom/moveTo are imported as separated redlines from fixing tdf#145718.
1032 // Accept the first inline moveFrom redline before accepting the remaining ones
1033 // to leave a paragraph long deletion to test the fix for tdf#125916.
1034 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
1035 CPPUNIT_ASSERT(pEditShell
);
1036 CPPUNIT_ASSERT(pEditShell
->GetRedlineCount() > 0);
1037 pEditShell
->AcceptRedline(0);
1039 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
1040 rIDRA
.AcceptAllRedline(true);
1042 // check unnecessary numbering
1043 uno::Reference
<beans::XPropertySet
> xProps(getParagraph(3), uno::UNO_QUERY_THROW
);
1044 CPPUNIT_ASSERT_MESSAGE("first paragraph after the first deletion: erroneous numbering",
1045 !xProps
->getPropertyValue(u
"NumberingRules"_ustr
).hasValue());
1048 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf125310
)
1050 createSwDoc("tdf125310.fodt");
1051 SwDoc
* pDoc
= getSwDoc();
1053 CPPUNIT_ASSERT_EQUAL(u
"Heading 1"_ustr
,
1054 getProperty
<OUString
>(getParagraph(1), u
"ParaStyleName"_ustr
));
1055 CPPUNIT_ASSERT_EQUAL(u
"Standard"_ustr
,
1056 getProperty
<OUString
>(getParagraph(2), u
"ParaStyleName"_ustr
));
1057 CPPUNIT_ASSERT_EQUAL(1, getPages());
1059 // turn on red-lining and show changes
1060 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
1061 | RedlineFlags::ShowInsert
);
1062 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1063 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1064 CPPUNIT_ASSERT_MESSAGE(
1065 "redlines should be visible",
1066 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
1069 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
1070 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1071 pWrtShell
->EndPara(/*bSelect=*/true);
1072 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1073 dispatchCommand(mxComponent
, u
".uno:Cut"_ustr
, {});
1075 // copied paragraph style
1076 CPPUNIT_ASSERT_EQUAL(u
"Heading 1"_ustr
,
1077 getProperty
<OUString
>(getParagraph(2), u
"ParaStyleName"_ustr
));
1079 // without copying the page break
1080 CPPUNIT_ASSERT_EQUAL(1, getPages());
1083 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf125310b
)
1085 createSwDoc("tdf125310b.fodt");
1086 SwDoc
* pDoc
= getSwDoc();
1087 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
1089 CPPUNIT_ASSERT_EQUAL(u
"Standard"_ustr
,
1090 getProperty
<OUString
>(getParagraph(2), u
"ParaStyleName"_ustr
));
1091 CPPUNIT_ASSERT_EQUAL(u
"Heading 1"_ustr
,
1092 getProperty
<OUString
>(getParagraph(3), u
"ParaStyleName"_ustr
));
1093 CPPUNIT_ASSERT_EQUAL(2, getPages());
1095 // turn on red-lining and show changes
1096 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
1097 | RedlineFlags::ShowInsert
);
1098 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1099 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1101 // remove second paragraph with the page break
1102 pWrtShell
->Down(/*bSelect=*/false);
1103 pWrtShell
->Down(/*bSelect=*/false);
1104 pWrtShell
->Up(/*bSelect=*/true);
1105 pWrtShell
->DelLeft();
1107 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
1108 rIDRA
.AcceptAllRedline(true);
1110 // losing the page break, as without redlining
1111 CPPUNIT_ASSERT_EQUAL(1, getPages());
1114 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf120336
)
1116 createSwDoc("tdf120336.docx");
1117 SwDoc
* pDoc
= getSwDoc();
1119 // turn on red-lining and show changes
1120 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
1121 | RedlineFlags::ShowInsert
);
1122 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1123 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1124 CPPUNIT_ASSERT_MESSAGE(
1125 "redlines should be visible",
1126 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
1128 CPPUNIT_ASSERT_EQUAL(2, getPages());
1130 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
1131 rIDRA
.AcceptAllRedline(true);
1133 // keep page break, as without redlining
1134 CPPUNIT_ASSERT_EQUAL(2, getPages());
1137 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf106843
)
1139 createSwDoc("tdf106843.docx");
1140 SwDoc
* pDoc
= getSwDoc();
1142 // try to turn off red-lining
1143 dispatchCommand(mxComponent
, u
".uno:TrackChanges"_ustr
, {});
1145 // but the protection doesn't allow it
1146 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1147 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1150 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testImageComment
)
1152 // Load a document with an as-char image in it.
1153 createSwDoc("image-comment.odt");
1154 SwDoc
* pDoc
= getSwDoc();
1155 SwView
* pView
= getSwDocShell()->GetView();
1157 // Test document has "before<image>after", remove the content before the image.
1158 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
1159 pWrtShell
->SttEndDoc(/*bStart=*/true);
1160 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 6, /*bBasicCall=*/false);
1161 pWrtShell
->Delete();
1163 // Select the image.
1166 // Insert a comment while the image is selected.
1167 pView
->GetViewFrame().GetDispatcher()->Execute(FN_POSTIT
, SfxCallMode::SYNCHRON
);
1169 // Verify that the comment is around the image.
1170 // Without the accompanying fix in place, this test would have failed, as FN_POSTIT was disabled
1171 // in the frame shell.
1172 // Then this test would have failed, as in case the as-char anchored image was at the start of
1173 // the paragraph, the comment of the image covered the character after the image, not the image.
1174 uno::Reference
<text::XTextRange
> xPara
= getParagraph(1);
1175 CPPUNIT_ASSERT_EQUAL(u
"Annotation"_ustr
,
1176 getProperty
<OUString
>(getRun(xPara
, 1), u
"TextPortionType"_ustr
));
1177 CPPUNIT_ASSERT_EQUAL(u
"Frame"_ustr
,
1178 getProperty
<OUString
>(getRun(xPara
, 2), u
"TextPortionType"_ustr
));
1179 CPPUNIT_ASSERT_EQUAL(u
"AnnotationEnd"_ustr
,
1180 getProperty
<OUString
>(getRun(xPara
, 3), u
"TextPortionType"_ustr
));
1181 CPPUNIT_ASSERT_EQUAL(u
"Text"_ustr
,
1182 getProperty
<OUString
>(getRun(xPara
, 4), u
"TextPortionType"_ustr
));
1184 // Insert content to the comment, and select the image again.
1185 SfxStringItem
aItem(FN_INSERT_STRING
, u
"x"_ustr
);
1186 pView
->GetViewFrame().GetDispatcher()->ExecuteList(FN_INSERT_STRING
, SfxCallMode::SYNCHRON
,
1190 #if !defined(MACOSX)
1191 // Calc the left edge of the as-char frame.
1192 SwRootFrame
* pLayout
= pWrtShell
->GetLayout();
1193 SwFrame
* pPage
= pLayout
->GetLower();
1194 SwFrame
* pBody
= pPage
->GetLower();
1195 SwFrame
* pTextFrame
= pBody
->GetLower();
1196 CPPUNIT_ASSERT(pTextFrame
->GetDrawObjs());
1197 const SwSortedObjs
& rAnchored
= *pTextFrame
->GetDrawObjs();
1198 CPPUNIT_ASSERT_GREATER(static_cast<size_t>(0), rAnchored
.size());
1199 SwAnchoredObject
* pObject
= rAnchored
[0];
1200 tools::Long nFrameLeft
= pObject
->GetObjRect().Left();
1201 tools::Long nFrameTop
= pObject
->GetObjRect().Top();
1203 // Make sure that the anchor points to the bottom left corner of the image.
1204 // Without the accompanying fix in place, this test would have failed with:
1205 // - Expected less or equal than: 1418
1207 // The anchor pointed to the bottom right corner, so as-char and at-char was inconsistent.
1208 Scheduler::ProcessEventsToIdle();
1209 SwPostItMgr
* pPostItMgr
= pView
->GetPostItMgr();
1210 for (const auto& pItem
: *pPostItMgr
)
1212 const SwRect
& rAnchor
= pItem
->mpPostIt
->GetAnchorRect();
1213 CPPUNIT_ASSERT_EQUAL(nFrameLeft
, rAnchor
.Left());
1216 // Test the comment anchor we expose via the LOK API.
1217 // Without the accompanying fix in place, this test would have failed with:
1218 // - Expected: 1418, 1418, 0, 0
1219 // - Actual : 1418, 1418, 1024, 1024
1220 // I.e. the anchor position had a non-empty size, which meant different rendering via tiled
1221 // rendering and on the desktop.
1222 tools::JsonWriter aJsonWriter
;
1223 SwXTextDocument
* pTextDoc
= getSwTextDoc();
1224 pTextDoc
->getPostIts(aJsonWriter
);
1225 OString pChar
= aJsonWriter
.finishAndGetAsOString();
1226 std::stringstream
aStream((std::string(pChar
)));
1227 boost::property_tree::ptree aTree
;
1228 boost::property_tree::read_json(aStream
, aTree
);
1229 for (const boost::property_tree::ptree::value_type
& rValue
: aTree
.get_child("comments"))
1231 const boost::property_tree::ptree
& rComment
= rValue
.second
;
1232 OString
aAnchorPos(rComment
.get
<std::string
>("anchorPos"));
1234 = OString::number(nFrameLeft
) + ", " + OString::number(nFrameTop
) + ", 0, 0";
1235 CPPUNIT_ASSERT_EQUAL(aExpected
, aAnchorPos
);
1240 // Now delete the image.
1241 pView
->GetViewFrame().GetDispatcher()->Execute(SID_DELETE
, SfxCallMode::SYNCHRON
);
1242 // Without the accompanying fix in place, this test would have failed with 'Expected: 0; Actual:
1243 // 1', i.e. the comment of the image was not deleted when the image was deleted.
1244 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0),
1245 pDoc
->getIDocumentMarkAccess()->getAnnotationMarksCount());
1248 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testImageCommentAtChar
)
1250 // Load a document with an at-char image in it.
1251 createSwDoc("image-comment-at-char.odt");
1252 SwDoc
* pDoc
= getSwDoc();
1253 SwView
* pView
= getSwDocShell()->GetView();
1255 // Select the image.
1258 // Insert a comment while the image is selected.
1259 pView
->GetViewFrame().GetDispatcher()->Execute(FN_POSTIT
, SfxCallMode::SYNCHRON
);
1261 // Verify that the comment is around the image.
1262 // Without the accompanying fix in place, this test would have failed, as the comment was
1263 // anchored at the end of the paragraph, it was not around the image.
1264 uno::Reference
<text::XTextRange
> xPara
= getParagraph(1);
1265 CPPUNIT_ASSERT_EQUAL(u
"Text"_ustr
,
1266 getProperty
<OUString
>(getRun(xPara
, 1), u
"TextPortionType"_ustr
));
1267 CPPUNIT_ASSERT_EQUAL(u
"Annotation"_ustr
,
1268 getProperty
<OUString
>(getRun(xPara
, 2), u
"TextPortionType"_ustr
));
1269 CPPUNIT_ASSERT_EQUAL(u
"Frame"_ustr
,
1270 getProperty
<OUString
>(getRun(xPara
, 3), u
"TextPortionType"_ustr
));
1271 CPPUNIT_ASSERT_EQUAL(u
"AnnotationEnd"_ustr
,
1272 getProperty
<OUString
>(getRun(xPara
, 4), u
"TextPortionType"_ustr
));
1273 CPPUNIT_ASSERT_EQUAL(u
"Text"_ustr
,
1274 getProperty
<OUString
>(getRun(xPara
, 5), u
"TextPortionType"_ustr
));
1276 // Insert content to the comment, and select the image again.
1277 SfxStringItem
aItem(FN_INSERT_STRING
, u
"x"_ustr
);
1278 pView
->GetViewFrame().GetDispatcher()->ExecuteList(FN_INSERT_STRING
, SfxCallMode::SYNCHRON
,
1281 // Now delete the image.
1282 pView
->GetViewFrame().GetDispatcher()->Execute(SID_DELETE
, SfxCallMode::SYNCHRON
);
1283 // Without the accompanying fix in place, this test would have failed with 'Expected: 0; Actual:
1284 // 1', i.e. the comment of the image was not deleted when the image was deleted.
1285 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0),
1286 pDoc
->getIDocumentMarkAccess()->getAnnotationMarksCount());
1288 // Undo the deletion and move the image down, so the anchor changes.
1289 pView
->GetViewFrame().GetDispatcher()->Execute(SID_UNDO
, SfxCallMode::SYNCHRON
);
1290 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1),
1291 pDoc
->getIDocumentMarkAccess()->getAnnotationMarksCount());
1292 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
1293 Point aNewAnchor
= pWrtShell
->GetFlyRect().TopLeft();
1294 aNewAnchor
.Move(0, 600);
1295 pWrtShell
->SetFlyPos(aNewAnchor
);
1297 // Get the image anchor doc model position.
1298 SwFlyFrame
* pFly
= pWrtShell
->GetCurrFlyFrame(false);
1299 CPPUNIT_ASSERT(pFly
);
1300 SwFrameFormat
* pFlyFormat
= pFly
->GetFrameFormat();
1301 const SwPosition
* pImageAnchor
= pFlyFormat
->GetAnchor().GetContentAnchor();
1302 CPPUNIT_ASSERT(pImageAnchor
);
1304 // Get the annotation mark doc model start.
1305 auto it
= pDoc
->getIDocumentMarkAccess()->getAnnotationMarksBegin();
1306 CPPUNIT_ASSERT(it
!= pDoc
->getIDocumentMarkAccess()->getAnnotationMarksEnd());
1307 const sw::mark::MarkBase
* pMark
= *it
;
1308 const SwPosition
& rAnnotationMarkStart
= pMark
->GetMarkPos();
1310 // Without the accompanying fix in place, this test would have failed with:
1311 // - Expected: SwPosition (node 14, offset 15)
1312 // - Actual : SwPosition (node 12, offset 3)
1313 // This means moving the image anchor did not move the comment anchor / annotation mark, so the
1314 // image and its comment got out of sync.
1315 CPPUNIT_ASSERT_EQUAL(*pImageAnchor
, rAnnotationMarkStart
);
1318 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTrackImageDeletion
)
1320 // load a document with an image anchored to paragraph in it
1321 createSwDoc("image.odt");
1322 SwDoc
* pDoc
= getSwDoc();
1323 SwView
* pView
= getSwDocShell()->GetView();
1328 // turn on red-lining and show changes
1329 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
1331 rIDRA
.SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
| RedlineFlags::ShowInsert
);
1332 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1333 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1334 CPPUNIT_ASSERT_MESSAGE(
1335 "redlines should be visible",
1336 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
1338 // now delete the image with track changes
1339 pView
->GetViewFrame().GetDispatcher()->Execute(SID_DELETE
, SfxCallMode::SYNCHRON
);
1341 const SwRedlineTable
& rTable
= rIDRA
.GetRedlineTable();
1342 // this was 0 (missing recording of deletion of images)
1343 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), rTable
.size());
1345 uno::Reference
<beans::XPropertySet
> xShape(getShape(1), uno::UNO_QUERY
);
1346 // tdf#142701 this was AS_CHARACTER (convert AT_PARA to AT_CHAR to keep the layout)
1347 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER
,
1348 getProperty
<text::TextContentAnchorType
>(xShape
, u
"AnchorType"_ustr
));
1351 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTrackImageInsertion
)
1354 SwDoc
* pDoc
= getSwDoc();
1356 // turn on red-lining and show changes
1357 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
1359 rIDRA
.SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
| RedlineFlags::ShowInsert
);
1360 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1361 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1362 CPPUNIT_ASSERT_MESSAGE(
1363 "redlines should be visible",
1364 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
1366 // Insert an image with change tracking
1367 uno::Sequence
<beans::PropertyValue
> aArgs
= {
1368 comphelper::makePropertyValue(u
"FileName"_ustr
, createFileURL(u
"ole2.png")),
1370 dispatchCommand(mxComponent
, u
".uno:InsertGraphic"_ustr
, aArgs
);
1372 const SwRedlineTable
& rTable
= rIDRA
.GetRedlineTable();
1373 // this was 0 (missing recording of insertion of images)
1374 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), rTable
.size());
1377 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf120338
)
1379 createSwDoc("tdf120338.docx");
1381 CPPUNIT_ASSERT_EQUAL(sal_Int32(1),
1382 getProperty
<sal_Int32
>(getParagraph(2), u
"ParaAdjust"_ustr
)); // right
1383 CPPUNIT_ASSERT_EQUAL(sal_Int32(1),
1384 getProperty
<sal_Int32
>(getParagraph(3), u
"ParaAdjust"_ustr
)); // right
1385 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
1386 getProperty
<sal_Int32
>(getParagraph(4), u
"ParaAdjust"_ustr
)); // left
1387 CPPUNIT_ASSERT_EQUAL(sal_Int32(1),
1388 getProperty
<sal_Int32
>(getParagraph(5), u
"ParaAdjust"_ustr
)); // right
1390 CPPUNIT_ASSERT_EQUAL(u
""_ustr
,
1391 getProperty
<OUString
>(getParagraph(7), u
"NumberingStyleName"_ustr
));
1393 CPPUNIT_ASSERT_EQUAL(u
"WWNum2"_ustr
,
1394 getProperty
<OUString
>(getParagraph(8), u
"NumberingStyleName"_ustr
));
1396 CPPUNIT_ASSERT_EQUAL(u
"Heading 2"_ustr
,
1397 getProperty
<OUString
>(getParagraph(10), u
"ParaStyleName"_ustr
));
1398 CPPUNIT_ASSERT_EQUAL(u
"Heading 2"_ustr
,
1399 getProperty
<OUString
>(getParagraph(11), u
"ParaStyleName"_ustr
));
1401 // reject tracked paragraph adjustments
1402 dispatchCommand(mxComponent
, u
".uno:RejectAllTrackedChanges"_ustr
, {});
1404 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
1405 getProperty
<sal_Int32
>(getParagraph(2), u
"ParaAdjust"_ustr
)); // left
1406 CPPUNIT_ASSERT_EQUAL(sal_Int32(3),
1407 getProperty
<sal_Int32
>(getParagraph(3), u
"ParaAdjust"_ustr
)); // center
1408 CPPUNIT_ASSERT_EQUAL(sal_Int32(3),
1409 getProperty
<sal_Int32
>(getParagraph(4), u
"ParaAdjust"_ustr
)); // center
1410 CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
1411 getProperty
<sal_Int32
>(getParagraph(5), u
"ParaAdjust"_ustr
)); // left
1413 // tdf#126245 revert numbering changes
1414 CPPUNIT_ASSERT_EQUAL(u
"WWNum2"_ustr
,
1415 getProperty
<OUString
>(getParagraph(7), u
"NumberingStyleName"_ustr
));
1417 CPPUNIT_ASSERT_EQUAL(u
""_ustr
,
1418 getProperty
<OUString
>(getParagraph(8), u
"NumberingStyleName"_ustr
));
1420 // tdf#126243 revert paragraph styles
1421 CPPUNIT_ASSERT_EQUAL(u
"Standard"_ustr
,
1422 getProperty
<OUString
>(getParagraph(10), u
"ParaStyleName"_ustr
));
1423 CPPUNIT_ASSERT_EQUAL(u
"Heading 3"_ustr
,
1424 getProperty
<OUString
>(getParagraph(11), u
"ParaStyleName"_ustr
));
1427 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf120338_multiple_paragraph_join
)
1429 createSwDoc("redline-para-join.docx");
1431 CPPUNIT_ASSERT_EQUAL(u
"Heading 1"_ustr
,
1432 getProperty
<OUString
>(getParagraph(1), u
"ParaStyleName"_ustr
));
1433 CPPUNIT_ASSERT_EQUAL(u
"Heading 1"_ustr
,
1434 getProperty
<OUString
>(getParagraph(2), u
"ParaStyleName"_ustr
));
1435 CPPUNIT_ASSERT_EQUAL(u
"Heading 1"_ustr
,
1436 getProperty
<OUString
>(getParagraph(3), u
"ParaStyleName"_ustr
));
1438 // reject tracked paragraph styles
1439 dispatchCommand(mxComponent
, u
".uno:RejectAllTrackedChanges"_ustr
, {});
1441 CPPUNIT_ASSERT_EQUAL(u
"Heading 1"_ustr
,
1442 getProperty
<OUString
>(getParagraph(1), u
"ParaStyleName"_ustr
));
1443 CPPUNIT_ASSERT_EQUAL(u
"Heading 2"_ustr
,
1444 getProperty
<OUString
>(getParagraph(2), u
"ParaStyleName"_ustr
));
1445 CPPUNIT_ASSERT_EQUAL(u
"Heading 3"_ustr
,
1446 getProperty
<OUString
>(getParagraph(3), u
"ParaStyleName"_ustr
));
1449 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testShapePageMove
)
1451 // Load a document with 2 pages, shape on the first page.
1452 createSwDoc("shape-page-move.odt");
1453 SwDoc
* pDoc
= getSwDoc();
1454 SwView
* pView
= getSwDocShell()->GetView();
1455 // Make sure that the 2nd page is below the 1st one.
1456 pView
->SetViewLayout(/*nColumns=*/1, /*bBookMode=*/false);
1459 // Select the shape.
1462 // Move the shape down to the 2nd page.
1463 SfxInt32Item
aXItem(SID_ATTR_TRANSFORM_POS_X
, 4000);
1464 SfxInt32Item
aYItem(SID_ATTR_TRANSFORM_POS_Y
, 12000);
1465 pView
->GetViewFrame().GetDispatcher()->ExecuteList(SID_ATTR_TRANSFORM
, SfxCallMode::SYNCHRON
,
1466 { &aXItem
, &aYItem
});
1468 // Check if the shape anchor was moved to the 2nd page as well.
1469 auto pShapeFormats
= pDoc
->GetSpzFrameFormats();
1470 CPPUNIT_ASSERT(!pShapeFormats
->empty());
1471 auto it
= pShapeFormats
->begin();
1472 auto pShapeFormat
= *it
;
1473 const SwPosition
* pAnchor
= pShapeFormat
->GetAnchor().GetContentAnchor();
1474 CPPUNIT_ASSERT(pAnchor
);
1476 // Find out the node index of the 1st para on the 2nd page.
1477 SwRootFrame
* pLayout
= pDoc
->getIDocumentLayoutAccess().GetCurrentLayout();
1478 SwFrame
* pFirstPage
= pLayout
->Lower();
1479 SwFrame
* pSecondPage
= pFirstPage
->GetNext();
1480 CPPUNIT_ASSERT(pSecondPage
->IsLayoutFrame());
1481 SwFrame
* pBodyFrame
= static_cast<SwLayoutFrame
*>(pSecondPage
)->GetLower();
1482 CPPUNIT_ASSERT(pBodyFrame
->IsLayoutFrame());
1483 SwFrame
* pTextFrame
= static_cast<SwLayoutFrame
*>(pBodyFrame
)->GetLower();
1484 CPPUNIT_ASSERT(pTextFrame
->IsTextFrame());
1485 SwNodeOffset nNodeIndex
= static_cast<SwTextFrame
*>(pTextFrame
)->GetTextNodeFirst()->GetIndex();
1487 // Without the accompanying fix in place, this test would have failed with "Expected: 13;
1488 // Actual: 12", i.e. the shape was anchored to the last paragraph of the 1st page, not to a
1489 // paragraph on the 2nd page.
1490 CPPUNIT_ASSERT_EQUAL(nNodeIndex
, pAnchor
->GetNodeIndex());
1493 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testDateFormFieldInsertion
)
1496 SwDoc
* pDoc
= getSwDoc();
1497 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
1498 CPPUNIT_ASSERT(pMarkAccess
);
1499 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
1501 // Insert a date form field
1502 dispatchCommand(mxComponent
, u
".uno:DatePickerFormField"_ustr
, {});
1503 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
1505 // Check whether the fieldmark is created
1506 auto aIter
= pMarkAccess
->getAllMarksBegin();
1507 CPPUNIT_ASSERT(aIter
!= pMarkAccess
->getAllMarksEnd());
1508 ::sw::mark::Fieldmark
* pFieldmark
= dynamic_cast<::sw::mark::Fieldmark
*>(*aIter
);
1509 CPPUNIT_ASSERT(pFieldmark
);
1510 CPPUNIT_ASSERT_EQUAL(ODF_FORMDATE
, pFieldmark
->GetFieldname());
1512 // The date form field has the placeholder text in it
1513 uno::Reference
<text::XTextRange
> xPara
= getParagraph(1);
1514 CPPUNIT_ASSERT_EQUAL(vEnSpaces
, xPara
->getString());
1517 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
1518 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
1521 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
1522 aIter
= pMarkAccess
->getAllMarksBegin();
1523 CPPUNIT_ASSERT(aIter
!= pMarkAccess
->getAllMarksEnd());
1524 pFieldmark
= dynamic_cast<::sw::mark::Fieldmark
*>(*aIter
);
1525 CPPUNIT_ASSERT(pFieldmark
);
1526 CPPUNIT_ASSERT_EQUAL(ODF_FORMDATE
, pFieldmark
->GetFieldname());
1529 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testDateFormFieldContentOperations
)
1532 SwDoc
* pDoc
= getSwDoc();
1533 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
1534 CPPUNIT_ASSERT(pMarkAccess
);
1535 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
1537 // Insert a date form field
1538 dispatchCommand(mxComponent
, u
".uno:DatePickerFormField"_ustr
, {});
1539 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
1541 // Check whether the fieldmark is created
1542 auto aIter
= pMarkAccess
->getAllMarksBegin();
1543 CPPUNIT_ASSERT(aIter
!= pMarkAccess
->getAllMarksEnd());
1544 ::sw::mark::DateFieldmark
* pFieldmark
= dynamic_cast<::sw::mark::DateFieldmark
*>(*aIter
);
1545 CPPUNIT_ASSERT(pFieldmark
);
1546 CPPUNIT_ASSERT_EQUAL(ODF_FORMDATE
, pFieldmark
->GetFieldname());
1548 // Check the default content added by insertion
1549 uno::Reference
<text::XTextRange
> xPara
= getParagraph(1);
1550 CPPUNIT_ASSERT_EQUAL(vEnSpaces
, pFieldmark
->GetContent());
1552 // Set content to empty string
1553 pFieldmark
->ReplaceContent(u
""_ustr
);
1554 CPPUNIT_ASSERT_EQUAL(u
""_ustr
, pFieldmark
->GetContent());
1556 // Replace empty string with a valid content
1557 pFieldmark
->ReplaceContent(u
"2019-10-23"_ustr
);
1558 CPPUNIT_ASSERT_EQUAL(u
"2019-10-23"_ustr
, pFieldmark
->GetContent());
1561 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testDateFormFieldCurrentDateHandling
)
1564 SwDoc
* pDoc
= getSwDoc();
1565 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
1566 CPPUNIT_ASSERT(pMarkAccess
);
1567 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
1569 // Insert a date form field
1570 dispatchCommand(mxComponent
, u
".uno:DatePickerFormField"_ustr
, {});
1571 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
1573 // Check whether the fieldmark is created
1574 auto aIter
= pMarkAccess
->getAllMarksBegin();
1575 CPPUNIT_ASSERT(aIter
!= pMarkAccess
->getAllMarksEnd());
1576 ::sw::mark::DateFieldmark
* pFieldmark
= dynamic_cast<::sw::mark::DateFieldmark
*>(*aIter
);
1577 CPPUNIT_ASSERT(pFieldmark
);
1578 CPPUNIT_ASSERT_EQUAL(ODF_FORMDATE
, pFieldmark
->GetFieldname());
1580 // The default content is not a valid date
1581 uno::Reference
<text::XTextRange
> xPara
= getParagraph(1);
1582 CPPUNIT_ASSERT_EQUAL(vEnSpaces
, pFieldmark
->GetContent());
1583 std::pair
<bool, double> aResult
= pFieldmark
->GetCurrentDate();
1584 CPPUNIT_ASSERT(!aResult
.first
);
1586 // Check empty string
1587 pFieldmark
->ReplaceContent(u
""_ustr
);
1588 aResult
= pFieldmark
->GetCurrentDate();
1589 CPPUNIT_ASSERT(!aResult
.first
);
1592 // Set date format first
1593 sw::mark::Fieldmark::parameter_map_t
* pParameters
= pFieldmark
->GetParameters();
1594 (*pParameters
)[ODF_FORMDATE_DATEFORMAT
] <<= u
"YYYY/MM/DD"_ustr
;
1595 (*pParameters
)[ODF_FORMDATE_DATEFORMAT_LANGUAGE
] <<= u
"en-US"_ustr
;
1597 // Set date value and check whether the content is formatted correctly
1598 pFieldmark
->SetCurrentDate(48000.0);
1599 aResult
= pFieldmark
->GetCurrentDate();
1600 CPPUNIT_ASSERT(aResult
.first
);
1601 CPPUNIT_ASSERT_EQUAL(48000.0, aResult
.second
);
1602 CPPUNIT_ASSERT_EQUAL(u
"2031/06/01"_ustr
, pFieldmark
->GetContent());
1603 // Current date param contains date in a "standard format"
1604 OUString sCurrentDate
;
1605 auto pResult
= pParameters
->find(ODF_FORMDATE_CURRENTDATE
);
1606 if (pResult
!= pParameters
->end())
1608 pResult
->second
>>= sCurrentDate
;
1610 CPPUNIT_ASSERT_EQUAL(u
"2031-06-01"_ustr
, sCurrentDate
);
1613 #if !defined(_WIN32)
1614 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testDateFormFieldCurrentDateInvalidation
)
1617 SwDoc
* pDoc
= getSwDoc();
1618 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
1619 CPPUNIT_ASSERT(pMarkAccess
);
1620 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess
->getAllMarksCount());
1622 // Insert a date form field
1623 dispatchCommand(mxComponent
, u
".uno:DatePickerFormField"_ustr
, {});
1624 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
1626 // Check whether the fieldmark is created
1627 auto aIter
= pMarkAccess
->getAllMarksBegin();
1628 CPPUNIT_ASSERT(aIter
!= pMarkAccess
->getAllMarksEnd());
1629 ::sw::mark::DateFieldmark
* pFieldmark
= dynamic_cast<::sw::mark::DateFieldmark
*>(*aIter
);
1630 CPPUNIT_ASSERT(pFieldmark
);
1631 CPPUNIT_ASSERT_EQUAL(ODF_FORMDATE
, pFieldmark
->GetFieldname());
1634 sw::mark::Fieldmark::parameter_map_t
* pParameters
= pFieldmark
->GetParameters();
1635 pFieldmark
->SetCurrentDate(48000.0);
1636 std::pair
<bool, double> aResult
= pFieldmark
->GetCurrentDate();
1637 CPPUNIT_ASSERT(aResult
.first
);
1638 CPPUNIT_ASSERT_EQUAL(48000.0, aResult
.second
);
1640 // Do the layouting to trigger invalidation
1641 // Since we have the current date consistent with the field content
1642 // This invalidation won't change anything
1644 Scheduler::ProcessEventsToIdle();
1646 // Current date param contains date in a "standard format"
1647 OUString sCurrentDate
;
1648 auto pResult
= pParameters
->find(ODF_FORMDATE_CURRENTDATE
);
1649 if (pResult
!= pParameters
->end())
1651 pResult
->second
>>= sCurrentDate
;
1653 // We have the current date parameter set
1654 CPPUNIT_ASSERT_EQUAL(u
"2031-06-01"_ustr
, sCurrentDate
);
1656 // Now change the content of the field
1657 pFieldmark
->ReplaceContent(u
"[select date]"_ustr
);
1658 // Do the layouting to trigger invalidation
1660 Scheduler::ProcessEventsToIdle();
1662 sCurrentDate
.clear();
1663 pResult
= pParameters
->find(ODF_FORMDATE_CURRENTDATE
);
1664 if (pResult
!= pParameters
->end())
1666 pResult
->second
>>= sCurrentDate
;
1668 CPPUNIT_ASSERT_EQUAL(u
""_ustr
, sCurrentDate
);
1672 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testOleSaveWhileEdit
)
1674 // Enable LOK mode, otherwise OCommonEmbeddedObject::SwitchStateTo_Impl() will throw when it
1675 // finds out that the test runs headless.
1676 comphelper::LibreOfficeKit::setActive();
1678 // Load a document with a Draw doc in it.
1679 createSwDoc("ole-save-while-edit.odt");
1680 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
1684 // Start editing the OLE object.
1685 pWrtShell
->LaunchOLEObj();
1687 // Save the document without existing the OLE edit.
1688 uno::Reference
<frame::XStorable
> xStorable(mxComponent
, uno::UNO_QUERY
);
1689 xStorable
->storeToURL(maTempFile
.GetURL(), {});
1691 uno::Reference
<packages::zip::XZipFileAccess2
> xNameAccess
1692 = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory
),
1693 maTempFile
.GetURL());
1694 // Without the accompanying fix in place, this test would have failed: the OLE object lost its
1695 // replacement on save if the edit was active while saving.
1696 CPPUNIT_ASSERT(xNameAccess
->hasByName(u
"ObjectReplacements/Object 1"_ustr
));
1698 // Dispose the document while LOK is still active to avoid leaks.
1699 mxComponent
->dispose();
1700 mxComponent
.clear();
1701 comphelper::LibreOfficeKit::setActive(false);
1704 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf105330
)
1706 createSwDoc("tdf105330.odt");
1707 SwDoc
* pDoc
= getSwDoc();
1709 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
1710 pWrtShell
->Down(/*bSelect=*/false);
1711 SwView
* pView
= getSwDocShell()->GetView();
1712 SfxUInt16Item
aRows(SID_ATTR_TABLE_ROW
, 1);
1713 SfxUInt16Item
aColumns(SID_ATTR_TABLE_COLUMN
, 1);
1714 pView
->GetViewFrame().GetDispatcher()->ExecuteList(FN_INSERT_TABLE
, SfxCallMode::SYNCHRON
,
1715 { &aRows
, &aColumns
});
1717 sw::UndoManager
& rUndoManager
= pDoc
->GetUndoManager();
1718 rUndoManager
.Undo();
1720 // Without the accompanying fix in place, height was only 1 twips (practically invisible).
1721 // Require at least 12pt height (font size under the cursor), in twips.
1722 CPPUNIT_ASSERT_GREATEREQUAL(
1723 static_cast<tools::Long
>(240),
1724 pWrtShell
->GetVisibleCursor()->GetTextCursor().GetSize().getHeight());
1727 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf118311
)
1729 createSwDoc("tdf118311.fodt");
1731 // Jump to the first cell, selecting its content
1732 uno::Sequence
<beans::PropertyValue
> aSearch(comphelper::InitPropertySequence({
1733 { "SearchItem.SearchString", uno::Any(u
"a"_ustr
) },
1734 { "SearchItem.Backward", uno::Any(false) },
1736 dispatchCommand(mxComponent
, u
".uno:ExecuteSearch"_ustr
, aSearch
);
1738 // .uno:Cut doesn't remove the table, only the selected content of the first cell
1739 dispatchCommand(mxComponent
, u
".uno:Cut"_ustr
, {});
1741 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1742 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1744 // .uno:SelectAll selects the whole table, and UNO command Cut cuts it
1745 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
1746 dispatchCommand(mxComponent
, u
".uno:Cut"_ustr
, {});
1748 pXmlDoc
= parseLayoutDump();
1749 assertXPath(pXmlDoc
, "//page[1]//body/tab", 0);
1752 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testRedlineTableRowDeletion
)
1754 // load a 1-row table, and delete the row with enabled change tracking:
1755 // now the row is not deleted silently, but keeps the deleted cell contents,
1756 // and only accepting all of them will result the deletion of the table row.
1757 createSwDoc("tdf118311.fodt");
1758 SwDoc
* pDoc
= getSwDoc();
1760 // turn on red-lining and show changes
1761 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
1762 | RedlineFlags::ShowInsert
);
1763 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1764 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1765 CPPUNIT_ASSERT_MESSAGE(
1766 "redlines should be visible",
1767 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
1770 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1771 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1773 // delete table row with enabled change tracking
1774 // (HasTextChangesOnly property of the row will be false)
1775 dispatchCommand(mxComponent
, u
".uno:DeleteRows"_ustr
, {});
1777 // This was deleted without change tracking
1778 pXmlDoc
= parseLayoutDump();
1779 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1781 // accept the deletion of the content of the first cell
1782 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
1783 CPPUNIT_ASSERT(pEditShell
);
1784 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(2), pEditShell
->GetRedlineCount());
1785 pEditShell
->AcceptRedline(0);
1787 // table row was still not deleted
1788 pXmlDoc
= parseLayoutDump();
1789 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1791 // accept last redline
1792 pEditShell
->AcceptRedline(0);
1794 // table row (and the 1-row table) was deleted finally
1795 pXmlDoc
= parseLayoutDump();
1796 assertXPath(pXmlDoc
, "//page[1]//body/tab", 0);
1798 // Undo, and repeat the previous test, but only with deletion of the text content of the cells
1799 // (HasTextChangesOnly property will be removed by Undo)
1801 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
1802 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
1803 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
1805 // table exists again
1806 pXmlDoc
= parseLayoutDump();
1807 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1809 // delete table row with enabled change tracking
1810 dispatchCommand(mxComponent
, u
".uno:SelectRow"_ustr
, {});
1811 dispatchCommand(mxComponent
, u
".uno:Delete"_ustr
, {});
1813 // Table row still exists
1814 pXmlDoc
= parseLayoutDump();
1815 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1817 // accept the deletion of the content of the first cell
1818 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(2), pEditShell
->GetRedlineCount());
1819 pEditShell
->AcceptRedline(0);
1821 // table row was still not deleted
1822 pXmlDoc
= parseLayoutDump();
1823 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1825 // accept last redline
1826 pEditShell
->AcceptRedline(0);
1828 // table row (and the 1-row table) still exists
1829 // (HasTextChangesOnly property wasn't set for table row deletion)
1830 pXmlDoc
= parseLayoutDump();
1831 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1833 // Undo, and delete the row without change tracking
1835 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
1836 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
1837 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
1839 // table exists again
1840 pXmlDoc
= parseLayoutDump();
1841 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1843 // disable change tracking
1844 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete
1845 | RedlineFlags::ShowInsert
);
1847 CPPUNIT_ASSERT_MESSAGE("redlining should be off",
1848 !pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1850 // delete table row without change tracking
1851 dispatchCommand(mxComponent
, u
".uno:DeleteRows"_ustr
, {});
1853 // the table (row) was deleted
1854 pXmlDoc
= parseLayoutDump();
1855 assertXPath(pXmlDoc
, "//page[1]//body/tab", 0);
1858 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf150976
)
1860 // load a 1-row table, and delete the row with track changes
1861 createSwDoc("select-row.fodt");
1862 SwDoc
* pDoc
= getSwDoc();
1864 // turn on red-lining and show changes
1865 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
1866 | RedlineFlags::ShowInsert
);
1867 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1868 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1869 CPPUNIT_ASSERT_MESSAGE(
1870 "redlines should be visible",
1871 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
1874 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1875 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1876 // nested table in the last cell
1877 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell[2]/tab");
1879 // delete table row with enabled change tracking
1880 dispatchCommand(mxComponent
, u
".uno:DeleteRows"_ustr
, {});
1882 pXmlDoc
= parseLayoutDump();
1883 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1885 // deleted text content
1886 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
1887 CPPUNIT_ASSERT(pEditShell
);
1888 // This was 1 before fixing tdf#151478 (testSelectRowWithNestedTable)
1889 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(3), pEditShell
->GetRedlineCount());
1891 SwRootFrame
* pLayout
= pDoc
->getIDocumentLayoutAccess().GetCurrentLayout();
1892 SwFrame
* pPage
= pLayout
->Lower();
1893 SwFrame
* pBody
= pPage
->GetLower();
1894 SwFrame
* pTable
= pBody
->GetLower();
1895 CPPUNIT_ASSERT(pTable
->IsTabFrame());
1897 SwTabFrame
* pTabFrame
= static_cast<SwTabFrame
*>(pTable
);
1899 // This was false (not deleted row)
1900 CPPUNIT_ASSERT(pTabFrame
->GetTable()->HasDeletedRowOrCell());
1902 // accept all tracked changes
1903 dispatchCommand(mxComponent
, u
".uno:AcceptAllTrackedChanges"_ustr
, {});
1905 pXmlDoc
= parseLayoutDump();
1907 // tdf#151658 This was 1: not deleted table row (and table)
1908 assertXPath(pXmlDoc
, "//page[1]//body/tab", 0);
1911 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf151657
)
1913 // load a 1-row table, and delete the row with hidden track changes
1914 createSwDoc("select-row.fodt");
1915 SwDoc
* pDoc
= getSwDoc();
1917 // turn on red-lining and hide changes
1918 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
);
1919 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1920 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1921 CPPUNIT_ASSERT_MESSAGE("redlines should be invisible",
1922 !IDocumentRedlineAccess::IsShowChanges(
1923 pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
1926 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1927 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1928 // nested table in the last cell
1929 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell[2]/tab");
1931 // delete table row with enabled change tracking
1932 dispatchCommand(mxComponent
, u
".uno:DeleteRows"_ustr
, {});
1934 pXmlDoc
= parseLayoutDump();
1935 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1937 // deleted text content
1938 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
1939 CPPUNIT_ASSERT(pEditShell
);
1940 // This was 1 before fixing tdf#151478 (testSelectRowWithNestedTable)
1941 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(3), pEditShell
->GetRedlineCount());
1943 SwRootFrame
* pLayout
= pDoc
->getIDocumentLayoutAccess().GetCurrentLayout();
1944 SwFrame
* pPage
= pLayout
->Lower();
1945 SwFrame
* pBody
= pPage
->GetLower();
1946 SwFrame
* pTable
= pBody
->GetLower();
1947 CPPUNIT_ASSERT(pTable
->IsTabFrame());
1949 SwTabFrame
* pTabFrame
= static_cast<SwTabFrame
*>(pTable
);
1951 // This was false (not deleted row)
1952 CPPUNIT_ASSERT(pTabFrame
->GetTable()->HasDeletedRowOrCell());
1954 // accept all tracked changes
1955 dispatchCommand(mxComponent
, u
".uno:AcceptAllTrackedChanges"_ustr
, {});
1957 pXmlDoc
= parseLayoutDump();
1959 // tdf#151658 This was 1: not deleted table row (and table)
1960 assertXPath(pXmlDoc
, "//page[1]//body/tab", 0);
1963 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testSelectRowWithNestedTable
)
1965 // load a 1-row table, and select the row
1966 createSwDoc("select-row.fodt");
1969 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1970 assertXPath(pXmlDoc
, "//page[1]//body/tab");
1971 // nested table in the last cell
1972 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell[2]/tab");
1975 dispatchCommand(mxComponent
, u
".uno:EntireRow"_ustr
, {});
1976 // convert selected text content to uppercase
1977 dispatchCommand(mxComponent
, u
".uno:ChangeCaseToUpper"_ustr
, {});
1979 pXmlDoc
= parseLayoutDump();
1980 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row/cell[2]/tab/row/cell[1]/txt",
1982 // This was "a1" (bad selection of the table row)
1983 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row/cell[1]/txt[1]", u
"A1");
1984 // This was "nested-b1" (bad selection of the table row)
1985 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row/cell[2]/tab/row/cell[2]/txt",
1989 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf47979_row
)
1991 // load a 2-row table, and select row 2 by clicking before it
1992 createSwDoc("select-column.fodt");
1993 SwDoc
* pDoc
= getSwDoc();
1994 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
1995 CPPUNIT_ASSERT(pWrtShell
);
1997 SwRootFrame
* pLayout
= pDoc
->getIDocumentLayoutAccess().GetCurrentLayout();
1998 SwFrame
* pPage
= pLayout
->Lower();
1999 SwFrame
* pBody
= pPage
->GetLower();
2000 SwFrame
* pTable
= pBody
->GetLower()->GetNext();
2001 SwFrame
* pRow2
= pTable
->GetLower()->GetNext();
2002 const SwRect
& rRow2Rect
= pRow2
->getFrameArea();
2003 Point
ptRow(rRow2Rect
.Left(), rRow2Rect
.Top() + rRow2Rect
.Height() / 2);
2005 pWrtShell
->SelectTableRowCol(ptRow
);
2007 // convert selected text content to uppercase
2008 dispatchCommand(mxComponent
, u
".uno:ChangeCaseToUpper"_ustr
, {});
2010 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
2011 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row[1]/cell[1]/txt[1]", u
"a1");
2012 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row[1]/cell[2]/txt[1]", u
"b1");
2013 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row[2]/cell[2]/tab/row/cell[1]/txt",
2015 // This was "a2" (bad selection of the table row)
2016 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row[2]/cell[1]/txt[1]", u
"A2");
2017 // This was "nested-b1" (bad selection of the table row)
2018 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row[2]/cell[2]/tab/row/cell[2]/txt",
2022 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf47979_column
)
2024 // load a 2-row table, and select column B by clicking before them
2025 createSwDoc("select-column.fodt");
2026 SwDoc
* pDoc
= getSwDoc();
2027 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
2028 CPPUNIT_ASSERT(pWrtShell
);
2030 // select table column by using the middle point of the top border of column B
2031 SwRootFrame
* pLayout
= pDoc
->getIDocumentLayoutAccess().GetCurrentLayout();
2032 SwFrame
* pPage
= pLayout
->Lower();
2033 SwFrame
* pBody
= pPage
->GetLower();
2034 SwFrame
* pTable
= pBody
->GetLower()->GetNext();
2035 SwFrame
* pRow1
= pTable
->GetLower();
2036 SwFrame
* pCellB1
= pRow1
->GetLower()->GetNext();
2037 const SwRect
& rCellB1Rect
= pCellB1
->getFrameArea();
2038 Point
ptColumn(rCellB1Rect
.Left() + rCellB1Rect
.Width() / 2, rCellB1Rect
.Top() - 5);
2040 pWrtShell
->SelectTableRowCol(ptColumn
);
2042 // convert selected text content to uppercase
2043 dispatchCommand(mxComponent
, u
".uno:ChangeCaseToUpper"_ustr
, {});
2045 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
2047 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row[1]/cell[1]/txt[1]", u
"a1");
2048 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row[2]/cell[1]/txt[1]", u
"a2");
2049 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row[2]/cell[2]/tab/row/cell[1]/txt",
2051 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row[2]/cell[2]/tab/row/cell[2]/txt",
2053 // This was "b1" (bad selection of the table column)
2054 assertXPathContent(pXmlDoc
, "//page[1]//body/tab/row[1]/cell[2]/txt[1]", u
"B1");
2057 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testRedlineTableRowDeletionWithExport
)
2059 // load a 1-row table, and delete the row with enabled change tracking:
2060 // now the row is not deleted silently, but keeps the deleted cell contents,
2061 // and only accepting all of them will result the deletion of the table row.
2062 createSwDoc("tdf118311.fodt");
2063 SwDoc
* pDoc
= getSwDoc();
2065 // turn on red-lining and show changes
2066 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2067 | RedlineFlags::ShowInsert
);
2068 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2069 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2070 CPPUNIT_ASSERT_MESSAGE(
2071 "redlines should be visible",
2072 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2075 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
2076 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2078 // delete table row with enabled change tracking
2079 // (HasTextChangesOnly property of the row will be false)
2080 dispatchCommand(mxComponent
, u
".uno:DeleteRows"_ustr
, {});
2082 // Deleted text content with change tracking,
2083 // but not table deletion
2084 pXmlDoc
= parseLayoutDump();
2085 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2087 // Save it and load it back.
2088 saveAndReload(u
"writer8"_ustr
);
2091 // accept the deletion of the content of the first cell
2092 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
2093 CPPUNIT_ASSERT(pEditShell
);
2094 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(2), pEditShell
->GetRedlineCount());
2095 pEditShell
->AcceptRedline(0);
2097 // table row was still not deleted
2098 pXmlDoc
= parseLayoutDump();
2099 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2101 // accept last redline
2102 pEditShell
->AcceptRedline(0);
2104 // table row (and the 1-row table) was deleted finally
2105 // (working export/import of HasTextChangesOnly)
2106 pXmlDoc
= parseLayoutDump();
2107 assertXPath(pXmlDoc
, "//page[1]//body/tab", 0);
2110 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testRedlineTableRowDeletionWithDOCXExport
)
2112 // load a 1-row table, and delete the row with enabled change tracking:
2113 // now the row is not deleted silently, but keeps the deleted cell contents,
2114 // and only accepting all of them will result the deletion of the table row.
2115 createSwDoc("tdf118311.fodt");
2116 SwDoc
* pDoc
= getSwDoc();
2118 // turn on red-lining and show changes
2119 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2120 | RedlineFlags::ShowInsert
);
2121 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2122 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2123 CPPUNIT_ASSERT_MESSAGE(
2124 "redlines should be visible",
2125 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2128 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
2129 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2131 // delete table row with enabled change tracking
2132 // (HasTextChangesOnly property of the row will be false)
2133 dispatchCommand(mxComponent
, u
".uno:DeleteRows"_ustr
, {});
2135 // Deleted text content with change tracking,
2136 // but not table deletion
2137 pXmlDoc
= parseLayoutDump();
2138 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2140 // Save it to a DOCX and load it back.
2141 // Exporting change tracking of the row wasn't supported.
2142 // Also Manage Changes for the import.
2143 saveAndReload(u
"Office Open XML Text"_ustr
);
2146 // accept the deletion of the content of the first cell
2147 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
2148 CPPUNIT_ASSERT(pEditShell
);
2149 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(2), pEditShell
->GetRedlineCount());
2150 pEditShell
->AcceptRedline(0);
2152 // table row was still not deleted
2153 pXmlDoc
= parseLayoutDump();
2154 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2156 // accept last redline
2157 pEditShell
->AcceptRedline(0);
2159 // table row (and the 1-row table) was deleted finally
2160 // (working export/import of HasTextChangesOnly)
2161 pXmlDoc
= parseLayoutDump();
2162 assertXPath(pXmlDoc
, "//page[1]//body/tab", 0);
2165 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testRedlineDOCXTableInsertion
)
2167 // load a 3-row table inserted with change tracking by text to table conversion
2168 createSwDoc("TC-table-converttotable.docx");
2169 SwDoc
* pDoc
= getSwDoc();
2171 // check table count (1)
2172 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
2173 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
2175 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
2177 // reject the text insertions of the table cells (also reject deletion of the tabulated
2178 // text source of the table, which was used by the tracked text to table conversion)
2179 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
2180 CPPUNIT_ASSERT(pEditShell
);
2181 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(10), pEditShell
->GetRedlineCount());
2182 while (pEditShell
->GetRedlineCount())
2183 pEditShell
->RejectRedline(0);
2185 // rejecting all text insertions must undo the table insertion
2186 // This was 1 (remaining empty table after rejecting all table text insertions)
2187 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables
->getCount());
2190 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testRedlineDOCXTableMoveToFrame
)
2192 // load a table with tracked drag & drop: Table1 is the moveFrom,
2193 // Table2 is the moveTo - and framed - table
2194 createSwDoc("TC-table-DnD-move.docx");
2195 SwDoc
* pDoc
= getSwDoc();
2197 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
2198 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
2200 uno::Reference
<container::XNameAccess
> xTableNames
= xTextTablesSupplier
->getTextTables();
2201 // check table count (2)
2202 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables
->getCount());
2204 // accept tracked table moving, remaining table is Table2
2205 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
2206 rIDRA
.AcceptAllRedline(true);
2207 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
2208 CPPUNIT_ASSERT(xTableNames
->hasByName(u
"Table2"_ustr
));
2209 CPPUNIT_ASSERT(!xTableNames
->hasByName(u
"Table1"_ustr
));
2211 // Undo and reject tracked table moving, remaining table is Table1
2212 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2213 rIDRA
.AcceptAllRedline(false);
2214 // This was 2 (not deleted Table2 – framed)
2215 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
2216 CPPUNIT_ASSERT(xTableNames
->hasByName(u
"Table1"_ustr
));
2217 CPPUNIT_ASSERT(!xTableNames
->hasByName(u
"Table2"_ustr
));
2220 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf157662_AcceptInsertRedlineCutWithDeletion
)
2222 createSwDoc("tdf157662_redlineNestedInsertDelete.odt");
2223 SwDoc
* pDoc
= getSwDoc();
2225 // turn on red-lining and show changes
2226 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2227 | RedlineFlags::ShowInsert
);
2228 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2229 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2230 CPPUNIT_ASSERT_MESSAGE(
2231 "redlines should be visible",
2232 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2234 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
2235 CPPUNIT_ASSERT(pEditShell
);
2236 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(9), pEditShell
->GetRedlineCount());
2238 // Accept the insert that splitted into 3 parts .. accept all 3 of them
2239 pEditShell
->AcceptRedline(6);
2240 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(7), pEditShell
->GetRedlineCount());
2241 // The middle had a delete too, rejecting the delete will remove that redline too.
2242 pEditShell
->RejectRedline(6);
2243 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(6), pEditShell
->GetRedlineCount());
2245 // Accept insert that splitted into 4 parts, but separated to 2-2 parts, with another insert.
2246 // It will accept only 2 parts, that is not separated. It leave the deletion.
2247 pEditShell
->AcceptRedline(0);
2248 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(5), pEditShell
->GetRedlineCount());
2249 // Accepting the delete will remove that redline.
2250 // (only that one, as its other half is separated from it with an insert)
2251 pEditShell
->AcceptRedline(0);
2252 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(4), pEditShell
->GetRedlineCount());
2255 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf157662_RejectInsertRedlineCutWithDeletion
)
2257 createSwDoc("tdf157662_redlineNestedInsertDelete.odt");
2258 SwDoc
* pDoc
= getSwDoc();
2260 // turn on red-lining and show changes
2261 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2262 | RedlineFlags::ShowInsert
);
2263 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2264 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2265 CPPUNIT_ASSERT_MESSAGE(
2266 "redlines should be visible",
2267 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2269 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
2270 CPPUNIT_ASSERT(pEditShell
);
2271 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(9), pEditShell
->GetRedlineCount());
2273 // Reject the insert that splitted into 3 parts. reject all 3 of them
2274 // it even remove the deletion, that was on the 2. insert...
2275 pEditShell
->RejectRedline(6);
2276 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(6), pEditShell
->GetRedlineCount());
2278 // Reject insert that splitted into 4 parts, but separated to 2-2 parts, with another insert.
2279 // It will reject only 2 parts, that is not separated. It remove the deletion.
2280 pEditShell
->RejectRedline(0);
2281 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(4), pEditShell
->GetRedlineCount());
2284 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf157663_RedlineMoveRecognition
)
2286 createSwDoc("tdf157663_redlineMove.odt");
2287 SwDoc
* pDoc
= getSwDoc();
2289 // turn on red-lining and show changes
2290 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2291 | RedlineFlags::ShowInsert
);
2292 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2293 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2294 CPPUNIT_ASSERT_MESSAGE(
2295 "redlines should be visible",
2296 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2298 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
2299 CPPUNIT_ASSERT(pEditShell
);
2301 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(23), pEditShell
->GetRedlineCount());
2303 // Check if move redlines are recognised as moved, during import
2304 SwRedlineTable
& rTable
= pDoc
->getIDocumentRedlineAccess().GetRedlineTable();
2305 bool vMovedRedlines
[23]
2306 = { false, true, true, true, true, true, true, true, true, true, true, true,
2307 true, false, true, false, true, false, false, false, false, false, false };
2308 // 20. and 22. redline is a delete/insert redline with the same text "three".
2309 // they are not recognised as a move, because 22. redline is not a whole paragraph.
2310 // Note: delete/insert redlines that are just a part of a paragraph decided to be part of
2311 // a move, only if it is at least 6 character long and contain a space "" character.
2312 for (SwRedlineTable::size_type i
= 0; i
< rTable
.size(); i
++)
2314 CPPUNIT_ASSERT_EQUAL(vMovedRedlines
[i
], rTable
[i
]->GetMoved() > 0);
2317 // Check if accepting move redlines accept its pairs as well.
2318 pEditShell
->AcceptRedline(3); // "9 3/4"
2319 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(19), pEditShell
->GetRedlineCount());
2321 pEditShell
->AcceptRedline(1); // "sqrt(10)"
2322 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(17), pEditShell
->GetRedlineCount());
2324 pEditShell
->AcceptRedline(1); // "four"
2325 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(13), pEditShell
->GetRedlineCount());
2327 pEditShell
->AcceptRedline(3); // "six"
2328 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(11), pEditShell
->GetRedlineCount());
2330 pEditShell
->AcceptRedline(4); // "sqrt(17)"
2331 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(9), pEditShell
->GetRedlineCount());
2333 // Undo back all the 5 redline accepts
2334 for (int i
= 0; i
< 5; i
++)
2336 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2338 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(23), pEditShell
->GetRedlineCount());
2340 // Check if rejecting redlines reject its pairs as well.
2341 pEditShell
->RejectRedline(3); // "9 3/4"
2342 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(20), pEditShell
->GetRedlineCount());
2344 pEditShell
->RejectRedline(2); // "sqrt(10)"
2345 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(18), pEditShell
->GetRedlineCount());
2347 pEditShell
->RejectRedline(2); // "four"
2348 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(15), pEditShell
->GetRedlineCount());
2350 pEditShell
->RejectRedline(2); // "sqrt(17)"
2351 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(14), pEditShell
->GetRedlineCount());
2353 pEditShell
->RejectRedline(2); // "six"
2354 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(12), pEditShell
->GetRedlineCount());
2356 const sal_uInt32 nZeroID
= 0;
2358 // Check if there are no more move redlines
2359 for (SwRedlineTable::size_type i
= 0; i
< rTable
.size(); i
++)
2361 CPPUNIT_ASSERT_EQUAL(nZeroID
, rTable
[i
]->GetMoved());
2364 // Check if moving paragraphs generate redline moves
2366 // move a paragraph that has delete redlines inside of it
2367 // original text: "Seve ent teen"
2368 // deleted texts: "e " and " t"
2369 // moved new text: "Seventeen"
2370 pEditShell
->GotoRedline(6, true);
2371 pEditShell
->UpdateCursor();
2372 pEditShell
->MoveParagraph(SwNodeOffset(1));
2373 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(16), pEditShell
->GetRedlineCount());
2375 sal_uInt32 nMovedID
= rTable
[6]->GetMoved();
2376 //moved text from here
2377 CPPUNIT_ASSERT(nMovedID
> 0); // "Sev"
2378 CPPUNIT_ASSERT_EQUAL(nZeroID
, rTable
[7]->GetMoved()); // "e " deleted text not moved
2379 CPPUNIT_ASSERT_EQUAL(nMovedID
, rTable
[8]->GetMoved()); // "ent"
2380 CPPUNIT_ASSERT_EQUAL(nZeroID
, rTable
[9]->GetMoved()); // " t"
2381 CPPUNIT_ASSERT_EQUAL(nMovedID
, rTable
[10]->GetMoved()); // "teen"
2382 // moved text to here
2383 CPPUNIT_ASSERT_EQUAL(nMovedID
, rTable
[11]->GetMoved()); // "Seventeen"
2385 // move paragraph that has an insert redline inside of it
2386 // original text: "Eigen"
2387 // inserted text: "hte"
2388 // moved new text :"Eighteen"
2389 pEditShell
->GotoRedline(12, true);
2390 pEditShell
->UpdateCursor();
2391 pEditShell
->MoveParagraph(SwNodeOffset(-2));
2392 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(19), pEditShell
->GetRedlineCount());
2394 nMovedID
= rTable
[12]->GetMoved();
2395 // moved text to here
2396 CPPUNIT_ASSERT(nMovedID
> 0); // "Eighteen"
2397 // moved text from here
2398 CPPUNIT_ASSERT_EQUAL(nMovedID
, rTable
[13]->GetMoved()); // "Eigen"
2399 CPPUNIT_ASSERT_EQUAL(nMovedID
, rTable
[14]->GetMoved()); // "hte"
2400 CPPUNIT_ASSERT_EQUAL(nMovedID
, rTable
[15]->GetMoved()); // "en"
2402 //Check if accept work on both side of the redlines made by manual move paragraphs
2403 pEditShell
->AcceptRedline(13); // "Eigen"
2404 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(15), pEditShell
->GetRedlineCount());
2405 pEditShell
->AcceptRedline(11); // "Seventeen"
2406 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(10), pEditShell
->GetRedlineCount());
2408 //undo back the last 2 accept
2409 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2410 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2411 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(19), pEditShell
->GetRedlineCount());
2413 //Check if reject work on both side of the redlines made by manual move paragraphs
2414 pEditShell
->RejectRedline(13); // "Eigen"
2415 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(16), pEditShell
->GetRedlineCount());
2416 pEditShell
->RejectRedline(11); // "Seventeen"
2417 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(12), pEditShell
->GetRedlineCount());
2420 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf143215
)
2422 // load a table with tracked insertion of an empty row
2423 createSwDoc("TC-table-rowadd.docx");
2424 SwDoc
* pDoc
= getSwDoc();
2426 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
2427 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
2429 // check table count
2430 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
2432 // check table row count
2433 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
2434 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable
->getRows()->getCount());
2436 // reject insertion of the empty table row
2437 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
2438 rIDRA
.AcceptAllRedline(false);
2439 // This was 4 (remained empty row)
2440 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable
->getRows()->getCount());
2442 // Undo and accept insertion of the table row
2443 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2444 rIDRA
.AcceptAllRedline(true);
2445 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable
->getRows()->getCount());
2447 // delete it with change tracking, and accept the deletion
2448 dispatchCommand(mxComponent
, u
".uno:DeleteRows"_ustr
, {});
2449 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable
->getRows()->getCount());
2450 rIDRA
.AcceptAllRedline(true);
2451 // This was 4 (remained empty row)
2452 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable
->getRows()->getCount());
2455 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf150666
)
2457 // load a table with tracked insertion of an empty row
2458 createSwDoc("TC-table-rowadd.docx");
2460 // check table count
2461 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
2462 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
2464 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
2466 // check table row count
2467 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
2468 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable
->getRows()->getCount());
2470 // select the second row (tracked table row insertion)
2471 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
2472 pWrtShell
->Down(/*bSelect=*/false);
2474 // delete it, and accept all tracked changes
2475 dispatchCommand(mxComponent
, u
".uno:DeleteRows"_ustr
, {});
2476 dispatchCommand(mxComponent
, u
".uno:AcceptAllTrackedChanges"_ustr
, {});
2478 // This was 4 (it was not possible to delete only the tracked row insertions)
2479 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable
->getRows()->getCount());
2481 // insert a new table row with track changes
2482 dispatchCommand(mxComponent
, u
".uno:InsertRowsAfter"_ustr
, {});
2483 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable
->getRows()->getCount());
2485 // select and delete it
2486 pWrtShell
->Down(/*bSelect=*/false);
2487 dispatchCommand(mxComponent
, u
".uno:DeleteRows"_ustr
, {});
2488 dispatchCommand(mxComponent
, u
".uno:AcceptAllTrackedChanges"_ustr
, {});
2490 // This was 4 (it was not possible to delete own tracked row insertions)
2491 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable
->getRows()->getCount());
2494 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf150666_regression
)
2496 // load a table with tracked insertion of an empty row
2497 createSwDoc("TC-table-rowadd.docx");
2499 // check table count
2500 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
2501 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
2503 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
2505 // check table row count
2506 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
2507 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable
->getRows()->getCount());
2509 // select the second row (tracked table row insertion)
2510 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
2511 pWrtShell
->Down(/*bSelect=*/false);
2513 // insert a new table row with track changes
2514 dispatchCommand(mxComponent
, u
".uno:InsertRowsAfter"_ustr
, {});
2515 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTable
->getRows()->getCount());
2517 dispatchCommand(mxComponent
, u
".uno:RejectAllTrackedChanges"_ustr
, {});
2519 // This was 4 (the inserted table row wasn't tracked)
2520 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable
->getRows()->getCount());
2523 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf144748
)
2525 // load a table with an empty row, and an empty line before the table
2526 // (to allow the easy selection of the full text with the table)
2527 createSwDoc("tdf144748.fodt");
2528 SwDoc
* pDoc
= getSwDoc();
2530 // turn on red-lining and show changes
2531 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2532 | RedlineFlags::ShowInsert
);
2533 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2534 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2535 CPPUNIT_ASSERT_MESSAGE(
2536 "redlines should be visible",
2537 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2539 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
2540 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
2542 // there is a table in the text
2543 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
2545 // delete full text with the table and check Undo
2547 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
2548 dispatchCommand(mxComponent
, u
".uno:Delete"_ustr
, {});
2549 // this crashed LibreOffice
2550 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2552 // redo and check redline usage
2554 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
2555 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
2556 CPPUNIT_ASSERT(pEditShell
);
2557 // This was 2 (bad extra redline for the empty row of the deleted table)
2558 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), pEditShell
->GetRedlineCount());
2560 // accept deletion of the text, including the table with the empty row
2562 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
2563 rIDRA
.AcceptAllRedline(true);
2565 // no table left in the text
2566 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables
->getCount());
2569 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf147180
)
2571 // load a tracked table insertion (single redline)
2572 createSwDoc("tdf147180.fodt");
2573 SwDoc
* pDoc
= getSwDoc();
2575 // turn on red-lining and show changes
2576 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2577 | RedlineFlags::ShowInsert
);
2578 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2579 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2580 CPPUNIT_ASSERT_MESSAGE(
2581 "redlines should be visible",
2582 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2584 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
2585 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
2587 // there is a table in the text
2588 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
2590 // insert a character in the first cell with change tracking
2591 SwWrtShell
* const pWrtShell
= getSwDocShell()->GetWrtShell();
2592 pWrtShell
->Insert(u
"x"_ustr
);
2594 // reject all the changes, including table insertion
2596 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
2597 rIDRA
.AcceptAllRedline(/*bAccept=*/false);
2599 // no table left in the text
2601 // This was 1 (lost tracking of the table after modifying its text content)
2602 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables
->getCount());
2605 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf147180_empty_rows
)
2607 // load a tracked table insertion (single redline) with empty rows
2608 createSwDoc("tdf150824.fodt");
2609 SwDoc
* pDoc
= getSwDoc();
2611 // turn on red-lining and show changes
2612 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2613 | RedlineFlags::ShowInsert
);
2614 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2615 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2616 CPPUNIT_ASSERT_MESSAGE(
2617 "redlines should be visible",
2618 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2620 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
2621 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
2623 // there is a table in the text
2624 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
2626 // insert a character in the first cell with change tracking
2627 SwWrtShell
* const pWrtShell
= getSwDocShell()->GetWrtShell();
2628 pWrtShell
->Insert(u
"x"_ustr
);
2630 // reject all the changes, including table insertion
2632 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
2633 rIDRA
.AcceptAllRedline(/*bAccept=*/false);
2635 // no table left in the text
2637 // This was 1 (lost tracking of the empty rows after modifying table text content)
2638 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables
->getCount());
2641 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testRedlineTableColumnDeletion
)
2643 // load a table, and delete the first column with enabled change tracking:
2644 // now the column is not deleted silently, but keeps the deleted cell content,
2645 // and only accepting it will result the deletion of the table column.
2646 createSwDoc("tdf118311.fodt");
2647 SwDoc
* pDoc
= getSwDoc();
2649 // turn on red-lining and show changes
2650 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2651 | RedlineFlags::ShowInsert
);
2652 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2653 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2654 CPPUNIT_ASSERT_MESSAGE(
2655 "redlines should be visible",
2656 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2659 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
2660 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2661 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
2663 // delete table column with enabled change tracking
2664 // (HasTextChangesOnly property of the cell will be false)
2665 dispatchCommand(mxComponent
, u
".uno:DeleteColumns"_ustr
, {});
2667 pXmlDoc
= parseLayoutDump();
2668 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2669 // This was 1 (deleted cell without change tracking)
2670 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
2672 // accept the deletion
2673 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
2674 CPPUNIT_ASSERT(pEditShell
);
2675 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), pEditShell
->GetRedlineCount());
2676 pEditShell
->AcceptRedline(0);
2678 pXmlDoc
= parseLayoutDump();
2679 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2681 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 1);
2683 // Undo, and repeat the previous test, but only with deletion of the text content of the cells
2684 // (HasTextChangesOnly property will be removed by Undo)
2686 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2687 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2689 // first column exists again
2690 pXmlDoc
= parseLayoutDump();
2691 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2692 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
2694 // delete table column with enabled change tracking
2695 dispatchCommand(mxComponent
, u
".uno:SelectColumn"_ustr
, {});
2696 dispatchCommand(mxComponent
, u
".uno:Delete"_ustr
, {});
2698 // Table column still exists
2699 pXmlDoc
= parseLayoutDump();
2700 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2701 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
2703 // accept the deletion of the content of the first cell
2704 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), pEditShell
->GetRedlineCount());
2705 pEditShell
->AcceptRedline(0);
2707 // table column was still not deleted
2708 pXmlDoc
= parseLayoutDump();
2709 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2710 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
2712 // Undo, and delete the column without change tracking
2714 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2715 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2717 // table exists again
2718 pXmlDoc
= parseLayoutDump();
2719 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2720 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
2722 // disable change tracking
2723 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete
2724 | RedlineFlags::ShowInsert
);
2726 CPPUNIT_ASSERT_MESSAGE("redlining should be off",
2727 !pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2729 // delete table column without change tracking
2730 dispatchCommand(mxComponent
, u
".uno:DeleteColumns"_ustr
, {});
2732 // the table column was deleted
2733 pXmlDoc
= parseLayoutDump();
2734 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2735 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 1);
2738 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf156474
)
2740 // load a table, and insert a column with change tracking
2741 createSwDoc("tdf118311.fodt");
2742 SwDoc
* pDoc
= getSwDoc();
2744 // turn on red-lining and show changes
2745 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2746 | RedlineFlags::ShowInsert
);
2747 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2748 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2749 CPPUNIT_ASSERT_MESSAGE(
2750 "redlines should be visible",
2751 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2753 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
2754 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
2757 // there is a table in the text with two columns
2758 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
2759 uno::Reference
<text::XTextTable
> xTextTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
2760 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable
->getColumns()->getCount());
2762 // insert table column with enabled change tracking
2763 // (HasTextChangesOnly property of the cell will be false)
2764 dispatchCommand(mxComponent
, u
".uno:InsertColumnsBefore"_ustr
, {});
2767 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable
->getColumns()->getCount());
2769 // accept tracked changes: remove HasTextChangesOnly = false of the inserted cells
2770 dispatchCommand(mxComponent
, u
".uno:AcceptAllTrackedChanges"_ustr
, {});
2773 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable
->getColumns()->getCount());
2775 // delete the text content (dummy character of the previous text change) of the newly
2776 // inserted cell, and accept tracked changes
2777 SwWrtShell
* const pWrtShell
= getSwDocShell()->GetWrtShell();
2778 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
2779 dispatchCommand(mxComponent
, u
".uno:SwBackspace"_ustr
, {});
2780 dispatchCommand(mxComponent
, u
".uno:AcceptAllTrackedChanges"_ustr
, {});
2782 // This was 2 columns (not removed HasTextChangesOnly = false resulted column deletion
2783 // instead of deleting only content of the cell)
2784 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable
->getColumns()->getCount());
2787 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, tdf156475
)
2789 // load a table, and insert a row without change tracking,
2790 // and delete the first column with the empty cell in the second row with change tracking
2791 createSwDoc("tdf118311.fodt");
2792 SwDoc
* pDoc
= getSwDoc();
2794 // turn off red-lining and show changes
2795 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete
2796 | RedlineFlags::ShowInsert
);
2797 CPPUNIT_ASSERT_MESSAGE("redlining should be off",
2798 !pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2800 CPPUNIT_ASSERT_MESSAGE(
2801 "redlines should be visible",
2802 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2805 dispatchCommand(mxComponent
, u
".uno:InsertRowsAfter"_ustr
, {});
2808 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
2809 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2810 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 2);
2811 assertXPath(pXmlDoc
, "//page[1]//body/tab/row[1]/cell", 2);
2812 assertXPath(pXmlDoc
, "//page[1]//body/tab/row[2]/cell", 2);
2814 // turn on red-lining
2815 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2816 | RedlineFlags::ShowInsert
);
2817 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2818 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2820 // delete table column with enabled change tracking
2821 // (HasTextChangesOnly property of the cell will be false)
2822 dispatchCommand(mxComponent
, u
".uno:DeleteColumns"_ustr
, {});
2824 // go down to the empty cell
2825 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
2826 pWrtShell
->Down(/*bSelect=*/false);
2828 // Without the fix in place, this couldn't work
2829 dispatchCommand(mxComponent
, u
".uno:AcceptTrackedChange"_ustr
, {});
2831 pXmlDoc
= parseLayoutDump();
2832 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2833 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 2);
2834 assertXPath(pXmlDoc
, "//page[1]//body/tab/row[1]/cell", 1);
2835 assertXPath(pXmlDoc
, "//page[1]//body/tab/row[2]/cell", 1);
2838 for (sal_Int32 i
= 0; i
< 4; ++i
)
2840 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2843 for (sal_Int32 i
= 0; i
< 4; ++i
)
2845 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
2849 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf155747
)
2851 // load a table, and delete the first column with enabled change tracking:
2852 // now the column is not deleted silently, but keeps the deleted cell content,
2853 // and only accepting it will result the deletion of the table column.
2854 createSwDoc("tdf118311.fodt");
2855 SwDoc
* pDoc
= getSwDoc();
2857 // turn on red-lining and show changes
2858 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2859 | RedlineFlags::ShowInsert
);
2860 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2861 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2862 CPPUNIT_ASSERT_MESSAGE(
2863 "redlines should be visible",
2864 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2866 // delete table column with enabled change tracking
2867 // (HasTextChangesOnly property of the cell will be false)
2868 dispatchCommand(mxComponent
, u
".uno:DeleteColumns"_ustr
, {});
2871 dispatchCommand(mxComponent
, u
".uno:SelectTable"_ustr
, {});
2873 // Without the fix in place, this test would have crashed here
2874 dispatchCommand(mxComponent
, u
".uno:AcceptTrackedChange"_ustr
, {});
2876 // check removed column
2877 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
2878 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2879 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 1);
2882 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf156544
)
2884 // load a table, and insert a column without change tracking,
2885 // and delete the first column with the empty cell in the second row with change tracking
2886 createSwDoc("tdf118311.fodt");
2887 SwDoc
* pDoc
= getSwDoc();
2889 // turn off red-lining and show changes
2890 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete
2891 | RedlineFlags::ShowInsert
);
2892 CPPUNIT_ASSERT_MESSAGE("redlining should be off",
2893 !pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2895 CPPUNIT_ASSERT_MESSAGE(
2896 "redlines should be visible",
2897 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2899 // insert table column without change tracking
2900 // (HasTextChangesOnly property of the cell will be false)
2901 dispatchCommand(mxComponent
, u
".uno:InsertColumnsBefore"_ustr
, {});
2904 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
2905 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2906 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 1);
2907 assertXPath(pXmlDoc
, "//page[1]//body/tab/row[1]/cell", 3);
2909 // turn on red-lining
2910 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
2911 | RedlineFlags::ShowInsert
);
2912 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2913 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2915 // go to the empty column
2916 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
2917 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
2919 // delete table column with enabled change tracking
2920 // (HasTextChangesOnly property of the cell will be false)
2921 dispatchCommand(mxComponent
, u
".uno:DeleteColumns"_ustr
, {});
2923 pXmlDoc
= parseLayoutDump();
2924 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2925 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 1);
2927 // This was 2 (deleted column)
2928 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 3);
2930 // accept the deletion of the empty column
2931 dispatchCommand(mxComponent
, u
".uno:AcceptTrackedChange"_ustr
, {});
2933 pXmlDoc
= parseLayoutDump();
2934 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2935 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 1);
2936 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
2939 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
2941 pXmlDoc
= parseLayoutDump();
2942 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2943 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 1);
2944 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 3);
2946 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
2948 pXmlDoc
= parseLayoutDump();
2949 assertXPath(pXmlDoc
, "//page[1]//body/tab");
2950 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 1);
2951 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
2954 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf156487
)
2956 // load a table, and delete a column in Hide Changes mode
2957 createSwDoc("tdf118311.fodt");
2958 SwDoc
* pDoc
= getSwDoc();
2960 // turn on red-lining and hide changes
2961 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
);
2962 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
2963 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
2965 CPPUNIT_ASSERT_MESSAGE("redlines shouldn't be visible",
2966 !IDocumentRedlineAccess::IsShowChanges(
2967 pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
2969 // delete table column with enabled change tracking
2970 // (HasTextChangesOnly property of the cell will be false)
2971 dispatchCommand(mxComponent
, u
".uno:DeleteColumns"_ustr
, {});
2973 // Dump the rendering of the first page as an XML file.
2974 SwDocShell
* pShell
= getSwDocShell();
2975 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
2976 MetafileXmlDump dumper
;
2977 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
2978 CPPUNIT_ASSERT(pXmlDoc
);
2980 // This would be 2 without hiding the first cell
2981 assertXPath(pXmlDoc
, "/metafile/push/push/push/textarray/text", 1);
2984 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf149498
)
2986 // load a table, and delete the first column with enabled change tracking:
2987 // now the column is not deleted silently, but keeps the deleted cell content,
2988 // and only accepting it will result the deletion of the table column.
2989 createSwDoc("tdf149498.docx");
2991 // select table, copy, paste and Undo
2992 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
2993 dispatchCommand(mxComponent
, u
".uno:Copy"_ustr
, {});
2994 dispatchCommand(mxComponent
, u
".uno:Paste"_ustr
, {});
2996 // this would crash due to bookmark over cell boundary
2997 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3000 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf150673_RedlineTableColumnDeletionWithExport
)
3002 // load a table, and delete the first column with enabled change tracking:
3003 // now the column is not deleted silently, but keeps the deleted cell contents,
3004 // and only accepting all of them will result the deletion of the table column.
3005 createSwDoc("tdf118311.fodt");
3006 SwDoc
* pDoc
= getSwDoc();
3008 // turn on red-lining and show changes
3009 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
3010 | RedlineFlags::ShowInsert
);
3011 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3012 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
3013 CPPUNIT_ASSERT_MESSAGE(
3014 "redlines should be visible",
3015 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
3018 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
3019 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3021 // delete table column with enabled change tracking
3022 // (HasTextChangesOnly property of the cell will be false)
3023 dispatchCommand(mxComponent
, u
".uno:DeleteColumns"_ustr
, {});
3025 // Deleted text content with change tracking,
3026 // but not table deletion
3027 pXmlDoc
= parseLayoutDump();
3028 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3029 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
3031 // Save it and load it back.
3032 saveAndReload(u
"writer8"_ustr
);
3035 // accept the deletion of the content of the first cell
3036 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
3037 CPPUNIT_ASSERT(pEditShell
);
3038 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), pEditShell
->GetRedlineCount());
3039 pEditShell
->AcceptRedline(0);
3041 // first table column was deleted finally
3042 // (working export/import of HasTextChangesOnly)
3043 pXmlDoc
= parseLayoutDump();
3044 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3045 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 1);
3047 // check removing HasTextChangesOnly at acceptance of the deletion
3049 // Undo, and delete the column without change tracking
3050 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3052 // table column exists again
3053 pXmlDoc
= parseLayoutDump();
3054 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3055 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
3057 // reject deletion, setting HasTextChangesOnly to TRUE
3058 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), pEditShell
->GetRedlineCount());
3059 pEditShell
->RejectRedline(0);
3060 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(0), pEditShell
->GetRedlineCount());
3062 // delete table column with enabled change tracking
3063 dispatchCommand(mxComponent
, u
".uno:SelectColumn"_ustr
, {});
3064 dispatchCommand(mxComponent
, u
".uno:Delete"_ustr
, {});
3066 // Table column still exists
3067 pXmlDoc
= parseLayoutDump();
3068 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3069 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
3071 // reject the deletion of the content of the first cell
3072 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), pEditShell
->GetRedlineCount());
3073 pEditShell
->AcceptRedline(0);
3075 // table column is still not deleted
3076 pXmlDoc
= parseLayoutDump();
3077 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3078 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
3081 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testRedlineTableColumnDeletionWithDOCXExport
)
3083 // load a 1-row table, and delete the first column with enabled change tracking:
3084 createSwDoc("tdf118311.fodt");
3085 SwDoc
* pDoc
= getSwDoc();
3087 // turn on red-lining and show changes
3088 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
3089 | RedlineFlags::ShowInsert
);
3090 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3091 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
3092 CPPUNIT_ASSERT_MESSAGE(
3093 "redlines should be visible",
3094 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
3097 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
3098 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3099 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
3101 // delete first table column with enabled change tracking
3102 // (HasTextChangesOnly property of the cell will be false)
3103 dispatchCommand(mxComponent
, u
".uno:DeleteColumns"_ustr
, {});
3105 // Deleted text content with change tracking,
3106 // but not table deletion
3107 pXmlDoc
= parseLayoutDump();
3108 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3109 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
3111 // Save it to a DOCX and load it back.
3112 // Exporting change tracking of the cell wasn't supported.
3113 // Also Manage Changes for the import.
3114 saveAndReload(u
"Office Open XML Text"_ustr
);
3117 // accept the deletion of the content of the first cell
3118 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
3119 CPPUNIT_ASSERT(pEditShell
);
3120 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), pEditShell
->GetRedlineCount());
3121 pEditShell
->AcceptRedline(0);
3123 // table column was deleted
3124 // (working export/import of HasTextChangesOnly of table cells)
3125 pXmlDoc
= parseLayoutDump();
3126 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3127 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 1);
3130 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf155341_RedlineTableColumnInsertionWithExport
)
3132 // load a table, and insert a new column with enabled change tracking
3133 createSwDoc("tdf118311.fodt");
3134 SwDoc
* pDoc
= getSwDoc();
3136 // turn on red-lining and show changes
3137 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
3138 | RedlineFlags::ShowInsert
);
3139 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3140 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
3141 CPPUNIT_ASSERT_MESSAGE(
3142 "redlines should be visible",
3143 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
3146 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
3147 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3149 // insert table column with enabled change tracking
3150 // (HasTextChangesOnly property of the cell will be false)
3151 dispatchCommand(mxComponent
, u
".uno:InsertColumnsAfter"_ustr
, {});
3153 // text content with change tracking (dummy redline)
3154 pXmlDoc
= parseLayoutDump();
3155 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3156 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 3);
3158 // Save it and load it back.
3159 saveAndReload(u
"writer8"_ustr
);
3162 // reject the insertion of the hidden content of the cell
3163 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
3164 CPPUNIT_ASSERT(pEditShell
);
3165 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), pEditShell
->GetRedlineCount());
3166 pEditShell
->RejectRedline(0);
3168 // inserted table column was deleted
3169 // (working export/import of HasTextChangesOnly)
3170 pXmlDoc
= parseLayoutDump();
3171 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3172 assertXPath(pXmlDoc
, "//page[1]//body/tab/row/cell", 2);
3175 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf128335
)
3177 // Load the bugdoc, which has 3 textboxes.
3178 createSwDoc("tdf128335.odt");
3180 // Select the 3rd textbox.
3181 SwView
* pView
= getSwDocShell()->GetView();
3183 SwXTextDocument
* pTextDoc
= getSwTextDoc();
3184 pTextDoc
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
3185 pTextDoc
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_TAB
);
3186 pTextDoc
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
3187 pTextDoc
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_TAB
);
3188 Scheduler::ProcessEventsToIdle();
3191 pView
->GetViewFrame().GetDispatcher()->Execute(SID_CUT
, SfxCallMode::SYNCHRON
);
3193 // Paste it: this makes the 3rd textbox anchored in the 2nd one.
3194 pView
->GetViewFrame().GetDispatcher()->Execute(SID_PASTE
, SfxCallMode::SYNCHRON
);
3199 // Without the accompanying fix in place, this test would have crashed as the textboxes were
3200 // deleted in an incorrect order.
3201 pView
->GetViewFrame().GetDispatcher()->Execute(SID_CUT
, SfxCallMode::SYNCHRON
);
3204 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testRedlineTableRowDeletionWithReject
)
3206 // load a 1-row table, and delete the row with enabled change tracking:
3207 // now the row is not deleted silently, but keeps the deleted cell contents,
3208 // and only accepting all of them will result the deletion of the table row.
3209 createSwDoc("tdf118311.fodt");
3210 SwDoc
* pDoc
= getSwDoc();
3212 // turn on red-lining and show changes
3213 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
3214 | RedlineFlags::ShowInsert
);
3215 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3216 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
3217 CPPUNIT_ASSERT_MESSAGE(
3218 "redlines should be visible",
3219 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
3222 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
3223 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3225 // delete table row with enabled change tracking
3226 // (HasTextChangesOnly property of the row will be false)
3227 dispatchCommand(mxComponent
, u
".uno:DeleteRows"_ustr
, {});
3229 // Deleted text content with change tracking,
3230 // but not table deletion
3231 pXmlDoc
= parseLayoutDump();
3232 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3234 // Save it and load it back.
3235 saveAndReload(u
"writer8"_ustr
);
3238 // reject the deletion of the content of the first cell
3239 // HasTextChangesOnly property of the table row will be true
3240 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
3241 CPPUNIT_ASSERT(pEditShell
);
3242 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(2), pEditShell
->GetRedlineCount());
3243 pEditShell
->RejectRedline(0);
3245 // Select and delete the content of the first cell
3246 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
3247 dispatchCommand(mxComponent
, u
".uno:Delete"_ustr
, {});
3249 // table row was still not deleted
3250 pXmlDoc
= parseLayoutDump();
3251 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3253 // accept all redlines
3254 while (pEditShell
->GetRedlineCount())
3255 pEditShell
->AcceptRedline(0);
3257 // This was table row deletion instead of remaining the empty row
3258 // (HasTextChangesOnly was false)
3259 pXmlDoc
= parseLayoutDump();
3260 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3262 // restore HasTextChangesOnly = false
3263 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3264 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3265 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3266 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3267 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3269 // accept all redlines
3270 while (pEditShell
->GetRedlineCount())
3271 pEditShell
->AcceptRedline(0);
3273 // table row (and the 1-row table) was deleted finally
3274 pXmlDoc
= parseLayoutDump();
3275 assertXPath(pXmlDoc
, "//page[1]//body/tab", 0);
3278 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testRedlineTableRowInsertionWithReject
)
3280 // load a 1-row table, and insert a row with enabled change tracking
3281 createSwDoc("tdf118311.fodt");
3282 SwDoc
* pDoc
= getSwDoc();
3284 // turn on red-lining and show changes
3285 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
3286 | RedlineFlags::ShowInsert
);
3287 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3288 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
3289 CPPUNIT_ASSERT_MESSAGE(
3290 "redlines should be visible",
3291 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
3293 // check table and its single row
3294 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
3295 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3296 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 1);
3298 // insert rows before and after with enabled change tracking
3299 // (HasTextChangesOnly property of the row will be false, and
3300 // add dummy characters CH_TXT_TRACKED_DUMMY_CHAR)
3301 dispatchCommand(mxComponent
, u
".uno:InsertRowsBefore"_ustr
, {});
3302 dispatchCommand(mxComponent
, u
".uno:InsertRowsAfter"_ustr
, {});
3304 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
3305 CPPUNIT_ASSERT(pEditShell
);
3306 // This was 0 (not tracked row insertion)
3307 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(2), pEditShell
->GetRedlineCount());
3309 pXmlDoc
= parseLayoutDump();
3310 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3311 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 3);
3314 pEditShell
->RejectRedline(0);
3315 pEditShell
->RejectRedline(0);
3317 pXmlDoc
= parseLayoutDump();
3318 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3319 // This was 3 (not rejected row insertion)
3320 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 1);
3323 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf145089_RedlineTableRowInsertionDOCX
)
3325 // load a 1-row table, and insert a row with enabled change tracking
3326 createSwDoc("tdf118311.fodt");
3327 SwDoc
* pDoc
= getSwDoc();
3329 // turn on red-lining and show changes
3330 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
3331 | RedlineFlags::ShowInsert
);
3332 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3333 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
3334 CPPUNIT_ASSERT_MESSAGE(
3335 "redlines should be visible",
3336 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
3338 // check table and its single row
3339 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
3340 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3341 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 1);
3343 // insert rows before and after with enabled change tracking
3344 // (HasTextChangesOnly property of the row will be false, and
3345 // add dummy characters CH_TXT_TRACKED_DUMMY_CHAR)
3346 dispatchCommand(mxComponent
, u
".uno:InsertRowsBefore"_ustr
, {});
3347 dispatchCommand(mxComponent
, u
".uno:InsertRowsAfter"_ustr
, {});
3350 saveAndReload(u
"Office Open XML Text"_ustr
);
3351 SwViewShell
* pViewShell
= getSwDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
3352 pViewShell
->Reformat();
3353 pXmlDoc
= parseLayoutDump();
3355 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3356 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 3);
3359 SwDoc
* pDOCXDoc(getSwDoc());
3360 SwEditShell
* const pEditShell(pDOCXDoc
->GetEditShell());
3361 CPPUNIT_ASSERT(pEditShell
);
3362 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(2), pEditShell
->GetRedlineCount());
3363 pEditShell
->RejectRedline(0);
3364 pEditShell
->RejectRedline(0);
3366 pXmlDoc
= parseLayoutDump();
3367 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3369 // This was 3 (not rejected row insertion)
3370 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 1);
3373 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testPasteTrackedTableRow
)
3375 // load a 1-row table
3376 createSwDoc("tdf118311.fodt");
3377 SwDoc
* pDoc
= getSwDoc();
3379 // turn on red-lining and show changes
3380 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
3381 | RedlineFlags::ShowInsert
);
3382 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3383 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
3384 CPPUNIT_ASSERT_MESSAGE(
3385 "redlines should be visible",
3386 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
3388 // check table count
3389 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
3390 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
3392 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
3394 // check table row count
3395 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
3396 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable
->getRows()->getCount());
3398 // copy table row and paste it by Paste Special->Rows Above
3399 dispatchCommand(mxComponent
, u
".uno:SelectTable"_ustr
, {});
3400 dispatchCommand(mxComponent
, u
".uno:Copy"_ustr
, {});
3401 dispatchCommand(mxComponent
, u
".uno:Escape"_ustr
, {});
3402 dispatchCommand(mxComponent
, u
".uno:PasteRowsBefore"_ustr
, {});
3405 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable
->getRows()->getCount());
3407 // This was 2 (inserted as a nested table in the first cell of the new row)
3408 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
3410 // Is it a tracked row insertion? Its rejection results the original 1-row table
3411 dispatchCommand(mxComponent
, u
".uno:RejectAllTrackedChanges"_ustr
, {});
3412 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable
->getRows()->getCount());
3414 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3415 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable
->getRows()->getCount());
3417 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
3418 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable
->getRows()->getCount());
3421 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testPasteTrackedTableRowInHideChangesMode
)
3423 // load a 1-row table
3424 createSwDoc("tdf118311.fodt");
3425 SwDoc
* pDoc
= getSwDoc();
3427 // turn on red-lining and show changes
3428 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
);
3429 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3430 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
3431 CPPUNIT_ASSERT_MESSAGE("redlines should be invisible",
3432 !IDocumentRedlineAccess::IsShowChanges(
3433 pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
3435 // check table count
3436 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
3437 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
3439 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
3441 // check table row count
3442 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
3443 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable
->getRows()->getCount());
3445 // copy table row and paste it by Paste Special->Rows Above
3446 dispatchCommand(mxComponent
, u
".uno:SelectTable"_ustr
, {});
3447 dispatchCommand(mxComponent
, u
".uno:Copy"_ustr
, {});
3448 dispatchCommand(mxComponent
, u
".uno:Escape"_ustr
, {});
3450 // This resulted freezing
3451 dispatchCommand(mxComponent
, u
".uno:PasteRowsBefore"_ustr
, {});
3454 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable
->getRows()->getCount());
3456 // This was 2 (inserted as a nested table in the first cell of the new row)
3457 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
3459 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3460 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3461 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {}); // FIXME Why 3 Undos?
3462 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable
->getRows()->getCount());
3464 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
3465 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable
->getRows()->getCount());
3468 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf146966
)
3470 // load a 4-row table, select more than 1 row and copy them
3471 // to check insertion of unnecessary empty rows
3472 createSwDoc("tdf144748.fodt");
3474 // check table row count
3475 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
3476 uno::Reference
<container::XIndexAccess
> xTables(xTextTablesSupplier
->getTextTables(),
3478 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables
->getCount());
3479 uno::Reference
<text::XTextTable
> xTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
3480 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable
->getRows()->getCount());
3482 // copy table row and paste it by Paste Special->Rows Above
3483 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
3484 pWrtShell
->Down(/*bSelect=*/false);
3485 dispatchCommand(mxComponent
, u
".uno:SelectTable"_ustr
, {});
3486 dispatchCommand(mxComponent
, u
".uno:Copy"_ustr
, {});
3487 dispatchCommand(mxComponent
, u
".uno:Escape"_ustr
, {});
3488 dispatchCommand(mxComponent
, u
".uno:PasteRowsBefore"_ustr
, {});
3490 // This was 35 (extra empty rows)
3491 CPPUNIT_ASSERT_EQUAL(sal_Int32(8), xTable
->getRows()->getCount());
3493 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3494 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3495 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {}); // FIXME Why 3 Undos?
3496 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable
->getRows()->getCount());
3498 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
3499 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
3500 CPPUNIT_ASSERT_EQUAL(sal_Int32(8), xTable
->getRows()->getCount());
3501 // dispatchCommand(mxComponent, ".uno:Redo", {}); // FIXME assert
3504 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf145091
)
3506 // load a deleted table, reject them, and delete only its text and export to DOCX
3507 createSwDoc("tdf145091.docx");
3508 SwDoc
* pDoc
= getSwDoc();
3510 // turn on red-lining and show changes
3511 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
3512 | RedlineFlags::ShowInsert
);
3513 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3514 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
3515 CPPUNIT_ASSERT_MESSAGE(
3516 "redlines should be visible",
3517 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
3519 // reject all redlines
3520 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
3521 CPPUNIT_ASSERT(pEditShell
);
3522 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(3), pEditShell
->GetRedlineCount());
3523 while (pEditShell
->GetRedlineCount() > 0)
3524 pEditShell
->RejectRedline(0);
3525 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(0), pEditShell
->GetRedlineCount());
3527 // delete only table text, but not table
3528 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
3529 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
3530 dispatchCommand(mxComponent
, u
".uno:Delete"_ustr
, {});
3531 CPPUNIT_ASSERT(pEditShell
->GetRedlineCount() > 0);
3534 saveAndReload(u
"Office Open XML Text"_ustr
);
3535 SwViewShell
* pViewShell
= getSwDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
3536 pViewShell
->Reformat();
3537 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
3539 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3540 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 3);
3542 // accept all redlines
3543 dispatchCommand(mxComponent
, u
".uno:AcceptAllTrackedChanges"_ustr
, {});
3545 pXmlDoc
= parseLayoutDump();
3546 // This was false (deleted table with accepting deletions)
3547 assertXPath(pXmlDoc
, "//page[1]//body/tab");
3548 assertXPath(pXmlDoc
, "//page[1]//body/tab/row", 3);
3551 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf128603
)
3553 // Load the bugdoc, which has 3 textboxes.
3554 createSwDoc("tdf128603.odt");
3555 SwDoc
* pDoc
= getSwDoc();
3557 // Select the 3rd textbox.
3558 SwView
* pView
= getSwDocShell()->GetView();
3560 SwXTextDocument
* pTextDoc
= getSwTextDoc();
3561 pTextDoc
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
3562 pTextDoc
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_TAB
);
3563 pTextDoc
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
3564 pTextDoc
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_TAB
);
3565 Scheduler::ProcessEventsToIdle();
3568 pView
->GetViewFrame().GetDispatcher()->Execute(SID_CUT
, SfxCallMode::SYNCHRON
);
3570 // Paste it: this makes the 3rd textbox anchored in the 2nd one.
3571 pView
->GetViewFrame().GetDispatcher()->Execute(SID_PASTE
, SfxCallMode::SYNCHRON
);
3573 // Undo all of this.
3574 sw::UndoManager
& rUndoManager
= pDoc
->GetUndoManager();
3575 rUndoManager
.Undo();
3576 rUndoManager
.Undo();
3578 // Make sure the content indexes still match.
3579 const auto& rSpzFrameFormats
= *pDoc
->GetSpzFrameFormats();
3580 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(6), rSpzFrameFormats
.size());
3581 const SwNodeIndex
* pIndex4
= rSpzFrameFormats
[4]->GetContent().GetContentIdx();
3582 CPPUNIT_ASSERT(pIndex4
);
3583 const SwNodeIndex
* pIndex5
= rSpzFrameFormats
[5]->GetContent().GetContentIdx();
3584 CPPUNIT_ASSERT(pIndex5
);
3585 // Without the accompanying fix in place, this test would have failed with:
3588 // i.e. the shape content index and the frame content index did not match after undo, even if
3589 // their "other text box format" pointers pointed to each other.
3590 CPPUNIT_ASSERT_EQUAL(pIndex4
->GetIndex(), pIndex5
->GetIndex());
3593 // only care that it doesn't assert/crash
3594 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testOfz18563
)
3596 OUString
sURL(m_directories
.getURLFromSrc(u
"/sw/qa/extras/uiwriter/data/ofz18563.docx"));
3597 SvFileStream
aFileStream(sURL
, StreamMode::READ
);
3598 TestImportDOCX(aFileStream
);
3601 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf143904
)
3603 createSwDoc("tdf143904.odt");
3604 SwDoc
* pDoc
= getSwDoc();
3606 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
3607 CPPUNIT_ASSERT(pWrtShell
);
3609 SwNodeOffset nIndex
= pWrtShell
->GetCursor()->GetPointNode().GetIndex();
3611 dispatchCommand(mxComponent
, u
".uno:InsertRowsAfter"_ustr
, {});
3612 pWrtShell
->Down(false);
3613 pWrtShell
->Insert(u
"foo"_ustr
);
3615 SwTextNode
* pTextNodeA1
= static_cast<SwTextNode
*>(pDoc
->GetNodes()[nIndex
]);
3616 CPPUNIT_ASSERT(pTextNodeA1
->GetText().startsWith("Insert"));
3617 nIndex
= pWrtShell
->GetCursor()->GetPointNode().GetIndex();
3618 SwTextNode
* pTextNodeA2
= static_cast<SwTextNode
*>(pDoc
->GetNodes()[nIndex
]);
3619 CPPUNIT_ASSERT_EQUAL(u
"foo"_ustr
, pTextNodeA2
->GetText());
3620 CPPUNIT_ASSERT_EQUAL(false, pTextNodeA2
->GetSwAttrSet().HasItem(RES_CHRATR_FONT
));
3621 OUString sFontName
= pTextNodeA2
->GetSwAttrSet().GetItem(RES_CHRATR_FONT
)->GetFamilyName();
3622 CPPUNIT_ASSERT_EQUAL(u
"Liberation Serif"_ustr
, sFontName
);
3625 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf90069
)
3627 createSwDoc("tdf90069.docx");
3628 SwDoc
* pDoc
= getSwDoc();
3630 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
3631 CPPUNIT_ASSERT(pWrtShell
);
3633 SwNodeOffset nIndex
= pWrtShell
->GetCursor()->GetPointNode().GetIndex();
3635 dispatchCommand(mxComponent
, u
".uno:InsertRowsAfter"_ustr
, {});
3636 pWrtShell
->Down(false);
3637 pWrtShell
->Insert(u
"foo"_ustr
);
3639 SwTextNode
* pTextNodeA1
= static_cast<SwTextNode
*>(pDoc
->GetNodes()[nIndex
]);
3640 CPPUNIT_ASSERT(pTextNodeA1
->GetText().startsWith("Insert"));
3641 nIndex
= pWrtShell
->GetCursor()->GetPointNode().GetIndex();
3642 SwTextNode
* pTextNodeA2
= static_cast<SwTextNode
*>(pDoc
->GetNodes()[nIndex
]);
3643 CPPUNIT_ASSERT_EQUAL(u
"foo"_ustr
, pTextNodeA2
->GetText());
3644 CPPUNIT_ASSERT_EQUAL(true, pTextNodeA2
->GetSwAttrSet().HasItem(RES_CHRATR_FONT
));
3645 OUString sFontName
= pTextNodeA2
->GetSwAttrSet().GetItem(RES_CHRATR_FONT
)->GetFamilyName();
3646 CPPUNIT_ASSERT_EQUAL(u
"Lohit Devanagari"_ustr
, sFontName
);
3649 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf109266
)
3651 // transliteration with redlining
3652 createSwDoc("lorem.fodt");
3653 SwDoc
* pDoc
= getSwDoc();
3654 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
3655 CPPUNIT_ASSERT(pWrtShell
);
3657 SwNodeOffset nIndex
= pWrtShell
->GetCursor()->GetPointNode().GetIndex();
3658 SwTextNode
* pTextNode
= static_cast<SwTextNode
*>(pDoc
->GetNodes()[nIndex
]);
3660 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum..."_ustr
, pTextNode
->GetText());
3661 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum..."_ustr
, pTextNode
->GetRedlineText());
3663 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
3664 dispatchCommand(mxComponent
, u
".uno:ChangeCaseToTitleCase"_ustr
, {});
3666 CPPUNIT_ASSERT_EQUAL(u
"Lorem Ipsum..."_ustr
, pTextNode
->GetText());
3667 CPPUNIT_ASSERT_EQUAL(u
"Lorem Ipsum..."_ustr
, pTextNode
->GetRedlineText());
3669 //turn on red-lining and show changes
3670 RedlineFlags
const mode(pWrtShell
->GetRedlineFlags() | RedlineFlags::On
);
3671 CPPUNIT_ASSERT(mode
& (RedlineFlags::ShowDelete
| RedlineFlags::ShowInsert
));
3672 pWrtShell
->SetRedlineFlags(mode
);
3673 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
3674 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
3675 CPPUNIT_ASSERT_MESSAGE(
3676 "redlines should be visible",
3677 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
3679 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3680 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
3681 dispatchCommand(mxComponent
, u
".uno:ChangeCaseToTitleCase"_ustr
, {});
3683 // This was "Lorem Ipsum..." (missing redlining)
3684 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsumIpsum..."_ustr
, pTextNode
->GetText());
3685 CPPUNIT_ASSERT_EQUAL(u
"Lorem Ipsum..."_ustr
, pTextNode
->GetRedlineText());
3687 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3688 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
3689 dispatchCommand(mxComponent
, u
".uno:ChangeCaseToUpper"_ustr
, {});
3691 // This was "LOREM IPSUM..." (missing redlining)
3692 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum...LOREM IPSUM..."_ustr
, pTextNode
->GetText());
3693 CPPUNIT_ASSERT_EQUAL(u
"LOREM IPSUM..."_ustr
, pTextNode
->GetRedlineText());
3695 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3696 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
3697 dispatchCommand(mxComponent
, u
".uno:ChangeCaseToLower"_ustr
, {});
3699 // This was "lorem ipsum..." (missing redlining)
3700 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum...lorem ipsum..."_ustr
, pTextNode
->GetText());
3701 CPPUNIT_ASSERT_EQUAL(u
"lorem ipsum..."_ustr
, pTextNode
->GetRedlineText());
3703 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3704 dispatchCommand(mxComponent
, u
".uno:SelectAll"_ustr
, {});
3705 dispatchCommand(mxComponent
, u
".uno:ChangeCaseToToggleCase"_ustr
, {});
3707 // This was "lOREM IPSUM..." (missing redlining)
3708 CPPUNIT_ASSERT_EQUAL(u
"Lorem ipsum...lOREM IPSUM..."_ustr
, pTextNode
->GetText());
3709 CPPUNIT_ASSERT_EQUAL(u
"lOREM IPSUM..."_ustr
, pTextNode
->GetRedlineText());
3712 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf129655
)
3714 createSwDoc("tdf129655-vtextbox.odt");
3715 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
3716 assertXPath(pXmlDoc
, "//anchored/fly/txt[@WritingMode='Vertical']", 1);
3719 static uno::Reference
<text::XTextRange
> getAssociatedTextRange(uno::Any object
)
3722 // 1. a container of other objects - e.g. selection of 0 to n text portions, or 1 to n drawing objects
3725 uno::Reference
<container::XIndexAccess
> xIndexAccess(object
, uno::UNO_QUERY_THROW
);
3726 if (xIndexAccess
.is() && xIndexAccess
->getCount() > 0)
3728 for (int i
= 0; i
< xIndexAccess
->getCount(); ++i
)
3730 uno::Reference
<text::XTextRange
> xRange
3731 = getAssociatedTextRange(xIndexAccess
->getByIndex(i
));
3737 catch (const uno::Exception
&)
3741 // 2. another TextContent, having an anchor we can use
3744 uno::Reference
<text::XTextContent
> xTextContent(object
, uno::UNO_QUERY_THROW
);
3745 if (xTextContent
.is())
3747 uno::Reference
<text::XTextRange
> xRange
= xTextContent
->getAnchor();
3752 catch (const uno::Exception
&)
3756 // an object which supports XTextRange directly
3759 uno::Reference
<text::XTextRange
> xRange(object
, uno::UNO_QUERY_THROW
);
3763 catch (const uno::Exception
&)
3770 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf123218
)
3772 struct ReverseXAxisOrientationDoughnutChart
3773 : public comphelper::ConfigurationProperty
<ReverseXAxisOrientationDoughnutChart
, bool>
3775 static OUString
path()
3777 return u
"/org.openoffice.Office.Compatibility/View/ReverseXAxisOrientationDoughnutChart"_ustr
;
3779 ~ReverseXAxisOrientationDoughnutChart() = delete;
3782 struct ClockwisePieChartDirection
3783 : public comphelper::ConfigurationProperty
<ClockwisePieChartDirection
, bool>
3785 static OUString
path()
3787 return u
"/org.openoffice.Office.Compatibility/View/ClockwisePieChartDirection"_ustr
;
3789 ~ClockwisePieChartDirection() = delete;
3791 auto batch
= comphelper::ConfigurationChanges::create();
3793 ReverseXAxisOrientationDoughnutChart::set(false, batch
);
3794 ClockwisePieChartDirection::set(true, batch
);
3799 // create an OLE shape in the document
3800 uno::Reference
<lang::XMultiServiceFactory
> xMSF(mxComponent
, uno::UNO_QUERY_THROW
);
3801 CPPUNIT_ASSERT(xMSF
);
3802 uno::Reference
<beans::XPropertySet
> xShapeProps(
3803 xMSF
->createInstance(u
"com.sun.star.text.TextEmbeddedObject"_ustr
), uno::UNO_QUERY
);
3804 xShapeProps
->setPropertyValue(u
"CLSID"_ustr
,
3805 uno::Any(u
"12dcae26-281f-416f-a234-c3086127382e"_ustr
));
3806 uno::Reference
<drawing::XShape
> xShape(xShapeProps
, uno::UNO_QUERY_THROW
);
3807 xShape
->setSize(awt::Size(16000, 9000));
3808 uno::Reference
<text::XTextContent
> chartTextContent(xShapeProps
, uno::UNO_QUERY_THROW
);
3809 uno::Reference
<frame::XModel
> xModel(mxComponent
, uno::UNO_QUERY
);
3810 uno::Reference
<view::XSelectionSupplier
> xSelSupplier(xModel
->getCurrentController(),
3811 uno::UNO_QUERY_THROW
);
3812 uno::Any aSelection
= xSelSupplier
->getSelection();
3813 uno::Reference
<text::XTextRange
> xTextRange
= getAssociatedTextRange(aSelection
);
3814 CPPUNIT_ASSERT(xTextRange
);
3815 xTextRange
->getText()->insertTextContent(xTextRange
, chartTextContent
, false);
3817 // insert a doughnut chart
3818 uno::Reference
<frame::XModel
> xDocModel
;
3819 xShapeProps
->getPropertyValue(u
"Model"_ustr
) >>= xDocModel
;
3820 CPPUNIT_ASSERT(xDocModel
);
3821 uno::Reference
<chart::XChartDocument
> xChartDoc(xDocModel
, uno::UNO_QUERY_THROW
);
3822 CPPUNIT_ASSERT(xChartDoc
);
3823 uno::Reference
<lang::XMultiServiceFactory
> xChartMSF(xChartDoc
, uno::UNO_QUERY_THROW
);
3824 CPPUNIT_ASSERT(xChartMSF
);
3825 uno::Reference
<chart::XDiagram
> xDiagram(
3826 xChartMSF
->createInstance(u
"com.sun.star.chart.DonutDiagram"_ustr
), uno::UNO_QUERY
);
3827 xChartDoc
->setDiagram(xDiagram
);
3829 // test primary X axis Orientation value
3830 uno::Reference
<chart2::XChartDocument
> xChartDoc2(xChartDoc
, uno::UNO_QUERY_THROW
);
3831 CPPUNIT_ASSERT(xChartDoc2
);
3832 uno::Reference
<chart2::XCoordinateSystemContainer
> xCooSysContainer(
3833 xChartDoc2
->getFirstDiagram(), uno::UNO_QUERY_THROW
);
3834 uno::Sequence
<uno::Reference
<chart2::XCoordinateSystem
>> xCooSysSequence
3835 = xCooSysContainer
->getCoordinateSystems();
3836 uno::Reference
<chart2::XCoordinateSystem
> xCoord
= xCooSysSequence
[0];
3837 CPPUNIT_ASSERT(xCoord
.is());
3838 uno::Reference
<chart2::XAxis
> xAxis
= xCoord
->getAxisByDimension(0, 0);
3839 CPPUNIT_ASSERT(xAxis
.is());
3840 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
3841 CPPUNIT_ASSERT_EQUAL(chart2::AxisOrientation_MATHEMATICAL
, aScaleData
.Orientation
);
3843 // tdf#108059 test primary Y axis Orientation value
3844 uno::Reference
<chart2::XAxis
> xYAxis
= xCoord
->getAxisByDimension(1, 0);
3845 CPPUNIT_ASSERT(xYAxis
.is());
3846 aScaleData
= xYAxis
->getScaleData();
3847 CPPUNIT_ASSERT_EQUAL(chart2::AxisOrientation_REVERSE
, aScaleData
.Orientation
);
3850 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf93747
)
3853 SwWrtShell
* pWrtSh
= getSwDocShell()->GetWrtShell();
3855 uno::Sequence
<beans::PropertyValue
> aArgs(comphelper::InitPropertySequence(
3856 { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));
3858 dispatchCommand(mxComponent
, u
".uno:InsertTable"_ustr
, aArgs
);
3860 pWrtSh
->Insert(u
"Col1"_ustr
);
3862 // Move the cursor to B1
3863 pWrtSh
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
3865 pWrtSh
->Insert(u
"Col2"_ustr
);
3867 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
3868 uno::Reference
<container::XIndexAccess
> xIndexAccess(xTextTablesSupplier
->getTextTables(),
3870 uno::Reference
<text::XTextTable
> xTextTable(xIndexAccess
->getByIndex(0), uno::UNO_QUERY
);
3871 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess
->getCount());
3872 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable
->getRows()->getCount());
3873 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable
->getColumns()->getCount());
3875 uno::Reference
<text::XTextRange
> xCellA1(xTextTable
->getCellByName(u
"A1"_ustr
), uno::UNO_QUERY
);
3876 CPPUNIT_ASSERT_EQUAL(u
"Col1"_ustr
, xCellA1
->getString());
3878 uno::Reference
<text::XTextRange
> xCellB1(xTextTable
->getCellByName(u
"B1"_ustr
), uno::UNO_QUERY
);
3879 CPPUNIT_ASSERT_EQUAL(u
"Col2"_ustr
, xCellB1
->getString());
3881 // Select backwards B1 and A1
3882 pWrtSh
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/true, 5, /*bBasicCall=*/false);
3884 // Just select the whole B1
3885 pWrtSh
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
3887 uno::Sequence
<beans::PropertyValue
> aPropertyValues
= comphelper::InitPropertySequence({
3888 { "Style", uno::Any(u
"Heading 1"_ustr
) },
3889 { "FamilyName", uno::Any(u
"ParagraphStyles"_ustr
) },
3891 dispatchCommand(mxComponent
, u
".uno:StyleApply"_ustr
, aPropertyValues
);
3893 // Without the fix in place, this test would have failed with
3894 // - Expected: Table Contents
3895 // - Actual : Heading 1
3896 CPPUNIT_ASSERT_EQUAL(
3897 u
"Table Contents"_ustr
,
3898 getProperty
<OUString
>(getParagraphOfText(1, xCellA1
->getText()), u
"ParaStyleName"_ustr
));
3900 CPPUNIT_ASSERT_EQUAL(
3902 getProperty
<OUString
>(getParagraphOfText(1, xCellB1
->getText()), u
"ParaStyleName"_ustr
));
3904 // Now select A1 again
3905 pWrtSh
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
3907 dispatchCommand(mxComponent
, u
".uno:StyleApply"_ustr
, aPropertyValues
);
3909 CPPUNIT_ASSERT_EQUAL(
3911 getProperty
<OUString
>(getParagraphOfText(1, xCellA1
->getText()), u
"ParaStyleName"_ustr
));
3913 CPPUNIT_ASSERT_EQUAL(
3915 getProperty
<OUString
>(getParagraphOfText(1, xCellB1
->getText()), u
"ParaStyleName"_ustr
));
3917 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3919 CPPUNIT_ASSERT_EQUAL(
3920 u
"Table Contents"_ustr
,
3921 getProperty
<OUString
>(getParagraphOfText(1, xCellA1
->getText()), u
"ParaStyleName"_ustr
));
3923 CPPUNIT_ASSERT_EQUAL(
3925 getProperty
<OUString
>(getParagraphOfText(1, xCellB1
->getText()), u
"ParaStyleName"_ustr
));
3927 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
3929 CPPUNIT_ASSERT_EQUAL(
3930 u
"Table Contents"_ustr
,
3931 getProperty
<OUString
>(getParagraphOfText(1, xCellA1
->getText()), u
"ParaStyleName"_ustr
));
3933 CPPUNIT_ASSERT_EQUAL(
3934 u
"Table Contents"_ustr
,
3935 getProperty
<OUString
>(getParagraphOfText(1, xCellB1
->getText()), u
"ParaStyleName"_ustr
));
3938 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf145151
)
3941 SwWrtShell
* pWrtSh
= getSwDocShell()->GetWrtShell();
3943 uno::Sequence
<beans::PropertyValue
> aArgs(comphelper::InitPropertySequence(
3944 { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));
3946 dispatchCommand(mxComponent
, u
".uno:InsertTable"_ustr
, aArgs
);
3948 pWrtSh
->Insert(u
"Col1"_ustr
);
3950 // Move the cursor to B1
3951 pWrtSh
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
3953 pWrtSh
->Insert(u
"Col2"_ustr
);
3955 uno::Reference
<text::XTextTablesSupplier
> xTextTablesSupplier(mxComponent
, uno::UNO_QUERY
);
3956 uno::Reference
<container::XIndexAccess
> xIndexAccess(xTextTablesSupplier
->getTextTables(),
3958 uno::Reference
<text::XTextTable
> xTextTable(xIndexAccess
->getByIndex(0), uno::UNO_QUERY
);
3959 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess
->getCount());
3960 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable
->getRows()->getCount());
3961 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable
->getColumns()->getCount());
3963 uno::Reference
<text::XTextRange
> xCellA1(xTextTable
->getCellByName(u
"A1"_ustr
), uno::UNO_QUERY
);
3964 CPPUNIT_ASSERT_EQUAL(u
"Col1"_ustr
, xCellA1
->getString());
3966 uno::Reference
<text::XTextRange
> xCellB1(xTextTable
->getCellByName(u
"B1"_ustr
), uno::UNO_QUERY
);
3967 CPPUNIT_ASSERT_EQUAL(u
"Col2"_ustr
, xCellB1
->getString());
3969 // Select backwards B1 and A1 (select "2loC<cell>" which ends up selecting both cells)
3970 pWrtSh
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/true, 5, /*bBasicCall=*/false);
3972 // Just select the whole B1
3973 pWrtSh
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
3975 dispatchCommand(mxComponent
, u
".uno:DefaultNumbering"_ustr
, {});
3977 // B1 should now have a numbering style, but A1 should not be affected.
3978 OUString sNumStyleB1
= getProperty
<OUString
>(getParagraphOfText(1, xCellB1
->getText()),
3979 u
"NumberingStyleName"_ustr
);
3980 CPPUNIT_ASSERT(!sNumStyleB1
.isEmpty());
3981 CPPUNIT_ASSERT_MESSAGE(
3982 "Only cell B1 was selected. A1 should not have any numbering.",
3983 getProperty
<OUString
>(getParagraphOfText(1, xCellA1
->getText()), u
"NumberingStyleName"_ustr
)
3986 // Toggle it back off
3987 dispatchCommand(mxComponent
, u
".uno:DefaultNumbering"_ustr
, {});
3989 CPPUNIT_ASSERT_MESSAGE(
3990 "Cell B1 must be able to toggle numbering on and off.",
3991 getProperty
<OUString
>(getParagraphOfText(1, xCellB1
->getText()), u
"NumberingStyleName"_ustr
)
3994 // Now test removing numbering/bullets
3995 // Add A1 to the current B1 selection
3996 pWrtSh
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
3998 // Toggle on bullet numbering
3999 dispatchCommand(mxComponent
, u
".uno:DefaultBullet"_ustr
, {});
4001 // sanity check - both cells have bullets turned on.
4002 OUString sNumStyleA1
= getProperty
<OUString
>(getParagraphOfText(1, xCellA1
->getText()),
4003 u
"NumberingStyleName"_ustr
);
4004 CPPUNIT_ASSERT(!sNumStyleA1
.isEmpty());
4005 CPPUNIT_ASSERT_EQUAL(sNumStyleA1
,
4006 getProperty
<OUString
>(getParagraphOfText(1, xCellB1
->getText()),
4007 u
"NumberingStyleName"_ustr
));
4008 CPPUNIT_ASSERT(sNumStyleA1
!= sNumStyleB1
); // therefore B1 changed from numbering to bullets
4010 // Just select cell B1
4011 pWrtSh
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
4013 // Toggle off bullet numbering
4014 dispatchCommand(mxComponent
, u
".uno:DefaultBullet"_ustr
, {});
4016 // B1 should now have removed all numbering, while A1 should still have the bullet.
4018 getProperty
<OUString
>(getParagraphOfText(1, xCellB1
->getText()), u
"NumberingStyleName"_ustr
)
4020 CPPUNIT_ASSERT_MESSAGE("Only cell B1 was selected. A1 should still have bullets turned on.",
4021 !getProperty
<OUString
>(getParagraphOfText(1, xCellA1
->getText()),
4022 u
"NumberingStyleName"_ustr
)
4025 // Toggle it back on
4026 dispatchCommand(mxComponent
, u
".uno:DefaultBullet"_ustr
, {});
4028 CPPUNIT_ASSERT(!getProperty
<OUString
>(getParagraphOfText(1, xCellB1
->getText()),
4029 u
"NumberingStyleName"_ustr
)
4033 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5
, testTdf126735
)
4035 createSwDoc("tdf39721.fodt");
4036 SwDoc
* pDoc
= getSwDoc();
4038 //turn on red-lining and show changes
4039 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
4040 | RedlineFlags::ShowInsert
);
4041 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
4042 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
4043 CPPUNIT_ASSERT_MESSAGE(
4044 "redlines should be visible",
4045 IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
4047 // check next selected tracked change
4048 dispatchCommand(mxComponent
, u
".uno:NextTrackedChange"_ustr
, {});
4049 uno::Reference
<frame::XModel
> xModel(mxComponent
, uno::UNO_QUERY
);
4050 uno::Reference
<view::XSelectionSupplier
> xSelSupplier(xModel
->getCurrentController(),
4051 uno::UNO_QUERY_THROW
);
4052 uno::Any aSelection
= xSelSupplier
->getSelection();
4053 uno::Reference
<text::XTextRange
> xTextRange
= getAssociatedTextRange(aSelection
);
4054 CPPUNIT_ASSERT(xTextRange
);
4055 CPPUNIT_ASSERT_EQUAL(u
" ipsu"_ustr
, xTextRange
->getString());
4057 // check next selected tracked change
4058 dispatchCommand(mxComponent
, u
".uno:NextTrackedChange"_ustr
, {});
4059 aSelection
= xSelSupplier
->getSelection();
4060 xTextRange
= getAssociatedTextRange(aSelection
);
4061 CPPUNIT_ASSERT(xTextRange
);
4062 CPPUNIT_ASSERT_EQUAL(u
"or "_ustr
, xTextRange
->getString());
4064 // check next selected tracked change at the end of the document:
4065 // select the first tracked change of the document
4066 dispatchCommand(mxComponent
, u
".uno:NextTrackedChange"_ustr
, {});
4067 aSelection
= xSelSupplier
->getSelection();
4068 xTextRange
= getAssociatedTextRange(aSelection
);
4069 CPPUNIT_ASSERT(xTextRange
);
4070 // This was empty (collapsing at the end of the last tracked change)
4071 CPPUNIT_ASSERT_EQUAL(u
" ipsu"_ustr
, xTextRange
->getString());
4073 // check the previous tracked change at the start of the document:
4074 // select the last tracked change of the document
4075 dispatchCommand(mxComponent
, u
".uno:PreviousTrackedChange"_ustr
, {});
4076 aSelection
= xSelSupplier
->getSelection();
4077 xTextRange
= getAssociatedTextRange(aSelection
);
4078 CPPUNIT_ASSERT(xTextRange
);
4079 // This was empty (collapsing at the start of the last tracked change)
4080 CPPUNIT_ASSERT_EQUAL(u
"or "_ustr
, xTextRange
->getString());
4083 CPPUNIT_PLUGIN_IMPLEMENT();
4085 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */