2 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of the LibreOffice project.
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 #include <com/sun/star/drawing/FillStyle.hpp>
12 #include <com/sun/star/style/CaseMap.hpp>
13 #include <swmodeltestbase.hxx>
16 #include <drawdoc.hxx>
17 #include <redline.hxx>
18 #include <dcontact.hxx>
20 #include <IDocumentSettingAccess.hxx>
22 #include <editeng/brushitem.hxx>
23 #include <svx/svdpage.hxx>
24 #include <svx/svdview.hxx>
26 #include <i18nutil/transliteration.hxx>
27 #include <IDocumentDrawModelAccess.hxx>
28 #include <IDocumentRedlineAccess.hxx>
29 #include <UndoManager.hxx>
30 #include <tblafmt.hxx>
32 #include <com/sun/star/text/XTextField.hpp>
33 #include <com/sun/star/linguistic2/XLinguProperties.hpp>
34 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
35 #include <com/sun/star/text/XPageCursor.hpp>
36 #include <com/sun/star/text/XParagraphAppend.hpp>
37 #include <o3tl/cppunittraitshelper.hxx>
38 #include <osl/thread.hxx>
40 #include <swdtflvr.hxx>
41 #include <comphelper/propertysequence.hxx>
42 #include <sfx2/classificationhelper.hxx>
43 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
44 #include <sfx2/viewfrm.hxx>
45 #include <sfx2/dispatch.hxx>
46 #include <editeng/unolingu.hxx>
47 #include <vcl/scheduler.hxx>
48 #include <config_fonts.h>
49 #include <unotxdoc.hxx>
50 #include <unotools/transliterationwrapper.hxx>
51 #include <officecfg/Office/Writer.hxx>
55 void lcl_selectCharacters(SwPaM
& rPaM
, sal_Int32 first
, sal_Int32 end
)
57 rPaM
.GetPoint()->nContent
.Assign(rPaM
.GetPointContentNode(), first
);
59 rPaM
.GetPoint()->nContent
.Assign(rPaM
.GetPointContentNode(), end
);
63 class SwUiWriterTest4
: public SwModelTestBase
67 : SwModelTestBase("/sw/qa/extras/uiwriter/data/")
71 void mergeDocs(const char* aDestDoc
, const char* aInsertDoc
);
74 void SwUiWriterTest4::mergeDocs(const char* aDestDoc
, const char* aInsertDoc
)
76 createSwDoc(aDestDoc
);
78 // set a page cursor into the end of the document
79 uno::Reference
<frame::XModel
> xModel(mxComponent
, uno::UNO_QUERY
);
80 uno::Reference
<text::XTextViewCursorSupplier
> xTextViewCursorSupplier(
81 xModel
->getCurrentController(), uno::UNO_QUERY
);
82 uno::Reference
<text::XPageCursor
> xCursor(xTextViewCursorSupplier
->getViewCursor(),
84 xCursor
->jumpToEndOfPage();
86 // insert the same document at current cursor position
88 const OUString insertFileid
= createFileURL(OUString::createFromAscii(aInsertDoc
));
89 uno::Sequence
<beans::PropertyValue
> aPropertyValues(
90 comphelper::InitPropertySequence({ { "Name", uno::Any(insertFileid
) } }));
91 dispatchCommand(mxComponent
, ".uno:InsertDoc", aPropertyValues
);
95 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf96515
)
97 // Enable hide whitespace mode.
99 SwDoc
* pDoc
= getSwDoc();
100 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
101 SwViewOption
aViewOptions(*pWrtShell
->GetViewOptions());
102 aViewOptions
.SetHideWhitespaceMode(true);
103 pWrtShell
->ApplyViewOptions(aViewOptions
);
104 CPPUNIT_ASSERT(pWrtShell
->GetViewOptions()->IsWhitespaceHidden());
106 // Insert a new paragraph at the end of the document.
107 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
108 uno::Reference
<text::XParagraphAppend
> xParagraphAppend(xTextDocument
->getText(),
110 xParagraphAppend
->finishParagraph(uno::Sequence
<beans::PropertyValue
>());
113 // This was 2, a new page was created for the new paragraph.
114 CPPUNIT_ASSERT_EQUAL(1, getPages());
117 static OUString
lcl_translitTest(SwDoc
& rDoc
, const SwPaM
& rPaM
, TransliterationFlags
const nType
)
119 utl::TransliterationWrapper
aTrans(::comphelper::getProcessComponentContext(), nType
);
120 rDoc
.getIDocumentContentOperations().TransliterateText(rPaM
, aTrans
);
121 //SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
122 return rPaM
.GetMarkNode().GetTextNode()->GetText();
125 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf146449
)
127 createSwDoc("tdf146449.odt");
129 auto pDoc
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
130 CPPUNIT_ASSERT(pDoc
);
131 auto pShell
= pDoc
->GetDocShell()->GetFEShell();
132 CPPUNIT_ASSERT(pShell
);
134 auto xTextBox
= getShapeByName(u
"Frame1");
135 auto pObject
= SdrObject::getSdrObjectFromXShape(xTextBox
);
137 CPPUNIT_ASSERT(pShell
->SelectObj(Point(), 0, pObject
));
139 dispatchCommand(mxComponent
, ".uno:Cut", {});
141 dispatchCommand(mxComponent
, ".uno:Undo", {});
143 uno::Reference
<beans::XPropertySet
> xShapeProps(xTextBox
, uno::UNO_QUERY
);
144 uno::Reference
<beans::XPropertySet
> xFrameProps(xShapeProps
->getPropertyValue("TextBoxContent"),
147 const auto& nShapeZOrder
= pObject
->GetOrdNum();
148 const auto& nFrameZOrder
= xFrameProps
->getPropertyValue("ZOrder");
150 CPPUNIT_ASSERT_MESSAGE("Wrong Zorder!", nShapeZOrder
< nFrameZOrder
.get
<sal_uInt32
>());
153 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf49033
)
156 SwDoc
* pDoc
= getSwDoc();
157 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
159 // Insert the test text at the end of the document.
160 pWrtShell
->SttEndDoc(/*bStt=*/false);
161 pWrtShell
->Insert("Mary Jones met joe Smith. Time Passed.");
162 pWrtShell
->StartOfSection();
163 SwShellCursor
* pCursor
= pWrtShell
->getShellCursor(false);
165 using TF
= TransliterationFlags
;
167 /* -- Test behavior when there is no selection -- */
169 /* Move cursor between the 't' and the ' ' after 'met', nothing should change */
170 for (int i
= 0; i
< 14; i
++)
171 pCursor
->Move(fnMoveForward
);
173 CPPUNIT_ASSERT_EQUAL(false, pCursor
->HasMark());
174 CPPUNIT_ASSERT_EQUAL(false, pWrtShell
->IsSelection());
175 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
176 lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
177 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
178 lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
179 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
180 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
181 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
182 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
184 /* Move cursor between the 'h' and the '.' after 'Smith', nothing should change */
185 for (int i
= 0; i
< 10; i
++)
186 pCursor
->Move(fnMoveForward
);
188 CPPUNIT_ASSERT_EQUAL(false, pCursor
->HasMark());
189 CPPUNIT_ASSERT_EQUAL(false, pWrtShell
->IsSelection());
190 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
191 lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
192 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
193 lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
194 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
195 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
196 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
197 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
199 /* Move cursor between the 'm' and the 'e' in 'met' */
200 for (int i
= 0; i
< 12; i
++)
201 pCursor
->Move(fnMoveBackward
);
203 CPPUNIT_ASSERT_EQUAL(false, pCursor
->HasMark());
204 CPPUNIT_ASSERT_EQUAL(false, pWrtShell
->IsSelection());
205 CPPUNIT_ASSERT_EQUAL(OUString("Mary jones met joe smith. Time Passed."),
206 lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
208 /* Undo the sentence case change to reset for the following tests */
209 pDoc
->GetIDocumentUndoRedo().Undo();
211 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."),
212 lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
213 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MET joe Smith. Time Passed."),
214 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
215 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
216 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
218 /* -- Test behavior when there is a selection that does not cross a word boundary -- */
219 pCursor
->Move(fnMoveBackward
);
221 CPPUNIT_ASSERT_EQUAL(true, pCursor
->HasMark());
222 CPPUNIT_ASSERT_EQUAL(true, pWrtShell
->IsSelection());
224 OUString currentSelectedText
;
225 pWrtShell
->GetSelectedText(currentSelectedText
);
226 CPPUNIT_ASSERT_EQUAL(OUString("met"), currentSelectedText
);
227 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."),
228 lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
229 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."),
230 lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
231 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MET joe Smith. Time Passed."),
232 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
233 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
234 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
236 /* -- Test behavior when there is a selection that does not begin at a word boundary: "et" -- */
237 for (int i
= 0; i
< 2; i
++)
238 pCursor
->Move(fnMoveBackward
);
240 for (int i
= 0; i
< 2; i
++)
241 pCursor
->Move(fnMoveForward
);
242 pWrtShell
->GetSelectedText(currentSelectedText
);
243 CPPUNIT_ASSERT_EQUAL(OUString("et"), currentSelectedText
);
244 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mEt joe Smith. Time Passed."),
245 lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
246 pDoc
->GetIDocumentUndoRedo().Undo();
247 CPPUNIT_ASSERT_EQUAL(OUString("et"), currentSelectedText
);
248 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mEt joe Smith. Time Passed."),
249 lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
250 pDoc
->GetIDocumentUndoRedo().Undo();
251 CPPUNIT_ASSERT_EQUAL(OUString("et"), currentSelectedText
);
252 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mET joe Smith. Time Passed."),
253 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
254 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
255 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
257 /* -- Test behavior when there is a selection that crosses a word boundary -- */
258 for (int i
= 0; i
< 7; i
++)
259 pCursor
->Move(fnMoveBackward
);
261 for (int i
= 0; i
< 14; i
++)
262 pCursor
->Move(fnMoveForward
);
264 pWrtShell
->GetSelectedText(currentSelectedText
);
265 CPPUNIT_ASSERT_EQUAL(OUString("nes met joe Sm"), currentSelectedText
);
266 CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNes met joe smith. Time Passed."),
267 lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
268 CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNes Met Joe Smith. Time Passed."),
269 lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
270 CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNES MET JOE SMith. Time Passed."),
271 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
272 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe smith. Time Passed."),
273 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
275 /* Reset the 's' to upper-case for the next test */
276 for (int i
= 0; i
< 2; i
++)
277 pCursor
->Move(fnMoveBackward
);
279 pCursor
->Move(fnMoveForward
);
280 pDoc
->getIDocumentContentOperations().ReplaceRange(*pCursor
, OUString('S'), false);
282 /* -- Test behavior when there is a selection that crosses a sentence boundary -- */
283 for (int i
= 0; i
< 4; i
++)
284 pCursor
->Move(fnMoveBackward
);
286 for (int i
= 0; i
< 22; i
++)
287 pCursor
->Move(fnMoveForward
);
288 pWrtShell
->GetSelectedText(currentSelectedText
);
289 CPPUNIT_ASSERT_EQUAL(OUString("joe Smith. Time Passed"), currentSelectedText
);
291 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met Joe smith. Time passed."),
292 lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
294 /* Undo the sentence case change to reset for the following tests */
295 pDoc
->GetIDocumentUndoRedo().Undo();
297 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met Joe Smith. Time Passed."),
298 lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
299 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met JOE SMITH. TIME PASSED."),
300 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
301 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe smith. time passed."),
302 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
304 /* Undo the previous changes to reset for the following tests */
305 pDoc
->GetIDocumentUndoRedo().Undo();
306 pDoc
->GetIDocumentUndoRedo().Undo();
307 pDoc
->GetIDocumentUndoRedo().Undo();
309 /* -- Test behavior when there is a selection that does not reach end of sentence -- */
310 for (int i
= 0; i
< 37; i
++)
311 pCursor
->Move(fnMoveBackward
);
313 for (int i
= 0; i
< 10; i
++)
314 pCursor
->Move(fnMoveForward
);
315 pWrtShell
->GetSelectedText(currentSelectedText
);
316 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones"), currentSelectedText
);
317 CPPUNIT_ASSERT_EQUAL(OUString("Mary jones met joe Smith. Time Passed."),
318 lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
319 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
320 lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
321 CPPUNIT_ASSERT_EQUAL(OUString("MARY JONES met joe Smith. Time Passed."),
322 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
323 CPPUNIT_ASSERT_EQUAL(OUString("mary jones met joe Smith. Time Passed."),
324 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
327 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf147196
)
329 using TF
= TransliterationFlags
;
331 SwDoc
* pDoc
= getSwDoc();
332 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
334 // Insert the test text at the end of the document.
335 pWrtShell
->SttEndDoc(/*bStt=*/false);
337 "2.2 Publication of information - CAA\nSection 4.2 of a CA\'s Certificate Policy and/or "
338 "Certification Practice Statement SHALL state the CA\'s policy or practice on processing "
339 "CAA Records for Fully Qualified Domain Names; that policy shall be consistent with these "
340 "Requirements. \n\nIt shall clearly specify the set of Issuer Domain Names that the CA "
341 "recognises in CAA \"issue\" or \"issuewild\" records as permitting it to issue. The CA "
342 "SHALL log all actions taken, if any, consistent with its processing practice.");
344 pWrtShell
->StartOfSection();
345 SwShellCursor
* pCursor
= pWrtShell
->getShellCursor(false);
347 for (int i
= 0; i
< 510; i
++)
349 pCursor
->Move(fnMoveForward
);
351 CPPUNIT_ASSERT_EQUAL(
352 OUString("2.2 Publication Of Information - Caa\nSection 4.2 Of A Ca\'s Certificate Policy "
353 "And/Or Certification Practice Statement Shall State The Ca\'s Policy Or Practice "
354 "On Processing Caa Records For Fully Qualified Domain Names; That Policy Shall Be "
355 "Consistent With These Requirements. \n\nIt Shall Clearly Specify The Set Of "
356 "Issuer Domain Names That The Ca Recognises In Caa \"Issue\" Or \"Issuewild\" "
357 "Records As Permitting It To Issue. The Ca Shall Log All Actions Taken, If Any, "
358 "Consistent With Its Processing Practice."),
359 lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
362 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf148148
)
364 using TF
= TransliterationFlags
;
366 SwDoc
* pDoc
= getSwDoc();
367 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
369 pWrtShell
->SttEndDoc(/*bStt=*/false);
370 pWrtShell
->Insert(" text");
372 /* Test what happens when node contains text but selection does not contain any text */
373 pWrtShell
->StartOfSection();
374 SwShellCursor
* pCursor
= pWrtShell
->getShellCursor(false);
376 for (int i
= 0; i
< 3; i
++)
378 pCursor
->Move(fnMoveForward
);
380 CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
381 CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
382 CPPUNIT_ASSERT_EQUAL(OUString(" text"),
383 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
384 CPPUNIT_ASSERT_EQUAL(OUString(" text"),
385 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
387 /* Test what happens when node contains text but selection does not contain any text */
390 pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
391 pWrtShell
->SttEndDoc(/*bStt=*/false);
392 pWrtShell
->Insert("text ");
394 pWrtShell
->StartOfSection();
395 pCursor
= pWrtShell
->getShellCursor(false);
396 for (int i
= 0; i
< 4; i
++)
398 pCursor
->Move(fnMoveForward
);
401 for (int i
= 0; i
< 2; i
++)
403 pCursor
->Move(fnMoveForward
);
406 CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
407 CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
408 CPPUNIT_ASSERT_EQUAL(OUString("text "),
409 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
410 CPPUNIT_ASSERT_EQUAL(OUString("text "),
411 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
413 /* Test what happens when node contains only non-word text but selection does not contain any text */
416 pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
417 pWrtShell
->SttEndDoc(/*bStt=*/false);
418 pWrtShell
->Insert("-1 ");
420 pWrtShell
->StartOfSection();
421 pCursor
= pWrtShell
->getShellCursor(false);
422 for (int i
= 0; i
< 2; i
++)
424 pCursor
->Move(fnMoveForward
);
427 for (int i
= 0; i
< 2; i
++)
429 pCursor
->Move(fnMoveForward
);
432 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
433 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
434 CPPUNIT_ASSERT_EQUAL(OUString("-1 "),
435 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
436 CPPUNIT_ASSERT_EQUAL(OUString("-1 "),
437 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
441 pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
442 pWrtShell
->SttEndDoc(/*bStt=*/false);
443 pWrtShell
->Insert(" -1");
445 pWrtShell
->StartOfSection();
446 pCursor
= pWrtShell
->getShellCursor(false);
448 for (int i
= 0; i
< 2; i
++)
450 pCursor
->Move(fnMoveForward
);
453 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
454 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
455 CPPUNIT_ASSERT_EQUAL(OUString(" -1"),
456 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
457 CPPUNIT_ASSERT_EQUAL(OUString(" -1"),
458 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
460 /* Test what happens when node and selection contains only non-word text */
463 pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
464 pWrtShell
->SttEndDoc(/*bStt=*/false);
465 pWrtShell
->Insert(" -1");
467 pWrtShell
->StartOfSection();
468 pCursor
= pWrtShell
->getShellCursor(false);
470 for (int i
= 0; i
< 5; i
++)
472 pCursor
->Move(fnMoveForward
);
475 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(*pDoc
, *pCursor
, TF::SENTENCE_CASE
));
476 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(*pDoc
, *pCursor
, TF::TITLE_CASE
));
477 CPPUNIT_ASSERT_EQUAL(OUString(" -1"),
478 lcl_translitTest(*pDoc
, *pCursor
, TF::LOWERCASE_UPPERCASE
));
479 CPPUNIT_ASSERT_EQUAL(OUString(" -1"),
480 lcl_translitTest(*pDoc
, *pCursor
, TF::UPPERCASE_LOWERCASE
));
483 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf96943
)
485 // Enable hide whitespace mode.
486 createSwDoc("tdf96943.odt");
487 SwDoc
* pDoc
= getSwDoc();
488 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
489 SwViewOption
aViewOptions(*pWrtShell
->GetViewOptions());
490 aViewOptions
.SetHideWhitespaceMode(true);
491 pWrtShell
->ApplyViewOptions(aViewOptions
);
493 // Insert a new character at the end of the document.
494 pWrtShell
->SttEndDoc(/*bStt=*/false);
495 pWrtShell
->Insert("d");
497 // This was 2, a new page was created for the new layout line.
498 CPPUNIT_ASSERT_EQUAL(1, getPages());
501 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf96536
)
503 // Enable hide whitespace mode.
505 SwDoc
* pDoc
= getSwDoc();
506 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
507 SwViewOption
aViewOptions(*pWrtShell
->GetViewOptions());
508 aViewOptions
.SetHideWhitespaceMode(true);
509 pWrtShell
->ApplyViewOptions(aViewOptions
);
510 CPPUNIT_ASSERT(pWrtShell
->GetViewOptions()->IsWhitespaceHidden());
512 // Insert a page break and go back to the first page.
513 pWrtShell
->InsertPageBreak();
514 pWrtShell
->SttEndDoc(/*bStt=*/true);
516 sal_Int32 nSingleParaPageHeight
= parseDump("/root/page[1]/infos/bounds", "height").toInt32();
517 discardDumpedLayout();
519 // Insert a 2nd paragraph at the end of the first page, so the page height grows at least twice...
520 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
521 uno::Reference
<text::XParagraphAppend
> xParagraphAppend(xTextDocument
->getText(),
523 const uno::Reference
<text::XTextRange
> xInsertPos
= getRun(getParagraph(1), 1);
524 xParagraphAppend
->finishParagraphInsert(uno::Sequence
<beans::PropertyValue
>(), xInsertPos
);
526 CPPUNIT_ASSERT(parseDump("/root/page[1]/infos/bounds", "height").toInt32()
527 >= 2 * nSingleParaPageHeight
);
528 discardDumpedLayout();
530 // ... and then delete the 2nd paragraph, which shrinks the page to the previous size.
531 uno::Reference
<lang::XComponent
> xParagraph(getParagraph(2), uno::UNO_QUERY
);
532 xParagraph
->dispose();
534 CPPUNIT_ASSERT_EQUAL(nSingleParaPageHeight
,
535 parseDump("/root/page[1]/infos/bounds", "height").toInt32());
538 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf96479
)
540 // We want to verify the empty input text field in the bookmark
541 static const OUString emptyInputTextField
542 = OUStringChar(CH_TXT_ATR_INPUTFIELDSTART
) + OUStringChar(CH_TXT_ATR_INPUTFIELDEND
);
545 SwDoc
* pDoc
= getSwDoc();
547 // So we can clean up all references for reload
550 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
552 IDocumentMarkAccess
& rIDMA
= *pDoc
->getIDocumentMarkAccess();
553 sw::mark::IMark
* pMark
= rIDMA
.makeMark(
554 aPaM
, "original", IDocumentMarkAccess::MarkType::BOOKMARK
, ::sw::mark::InsertMode::New
);
555 CPPUNIT_ASSERT(!pMark
->IsExpanded());
556 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getBookmarksCount());
558 // Get helper objects
559 uno::Reference
<text::XBookmarksSupplier
> xBookmarksSupplier(mxComponent
, uno::UNO_QUERY
);
560 uno::Reference
<css::lang::XMultiServiceFactory
> xFactory(mxComponent
, uno::UNO_QUERY
);
562 // Create cursor from bookmark
563 uno::Reference
<text::XTextContent
> xTextContent(
564 xBookmarksSupplier
->getBookmarks()->getByName("original"), uno::UNO_QUERY
);
565 uno::Reference
<text::XTextRange
> xRange
= xTextContent
->getAnchor();
566 uno::Reference
<text::XTextCursor
> xCursor
567 = xRange
->getText()->createTextCursorByRange(xRange
);
568 CPPUNIT_ASSERT(xCursor
->isCollapsed());
571 xRange
->getText()->removeTextContent(xTextContent
);
572 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rIDMA
.getBookmarksCount());
574 // Insert replacement bookmark
575 uno::Reference
<text::XTextContent
> xBookmarkNew(
576 xFactory
->createInstance("com.sun.star.text.Bookmark"), uno::UNO_QUERY
);
577 uno::Reference
<container::XNamed
> xBookmarkName(xBookmarkNew
, uno::UNO_QUERY
);
578 xBookmarkName
->setName("replacement");
579 CPPUNIT_ASSERT(xCursor
->isCollapsed());
580 // Force bookmark expansion
581 xCursor
->getText()->insertString(xCursor
, ".", true);
582 xCursor
->getText()->insertTextContent(xCursor
, xBookmarkNew
, true);
583 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getBookmarksCount());
584 auto mark
= *(rIDMA
.getBookmarksBegin());
585 CPPUNIT_ASSERT(mark
->IsExpanded());
587 // Create and insert input textfield with some content
588 uno::Reference
<text::XTextField
> xTextField(
589 xFactory
->createInstance("com.sun.star.text.TextField.Input"), uno::UNO_QUERY
);
590 uno::Reference
<text::XTextCursor
> xCursorNew(
591 xBookmarkNew
->getAnchor()->getText()->createTextCursorByRange(
592 xBookmarkNew
->getAnchor()));
593 CPPUNIT_ASSERT(!xCursorNew
->isCollapsed());
594 xCursorNew
->getText()->insertTextContent(xCursorNew
, xTextField
, true);
595 xBookmarkNew
= uno::Reference
<text::XTextContent
>(
596 xBookmarksSupplier
->getBookmarks()->getByName("replacement"), uno::UNO_QUERY
);
597 xCursorNew
= xBookmarkNew
->getAnchor()->getText()->createTextCursorByRange(
598 xBookmarkNew
->getAnchor());
599 CPPUNIT_ASSERT(!xCursorNew
->isCollapsed());
601 // Can't check the actual content of the text node via UNO
602 mark
= *(rIDMA
.getBookmarksBegin());
603 CPPUNIT_ASSERT(mark
->IsExpanded());
604 SwPaM
pam(mark
->GetMarkStart(), mark
->GetMarkEnd());
605 // Check for the actual bug, which didn't include CH_TXT_ATR_INPUTFIELDEND in the bookmark
606 CPPUNIT_ASSERT_EQUAL(emptyInputTextField
, pam
.GetText());
610 // Save and load cycle
611 // Actually not needed, but the bug symptom of a missing bookmark
612 // occurred because a broken bookmark was saved and loading silently
613 // dropped the broken bookmark!
614 saveAndReload("writer8");
617 // Lookup "replacement" bookmark
618 IDocumentMarkAccess
& rIDMA
= *pDoc
->getIDocumentMarkAccess();
619 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getBookmarksCount());
620 uno::Reference
<text::XBookmarksSupplier
> xBookmarksSupplier(mxComponent
, uno::UNO_QUERY
);
621 CPPUNIT_ASSERT(xBookmarksSupplier
->getBookmarks()->hasByName("replacement"));
623 uno::Reference
<text::XTextContent
> xTextContent(
624 xBookmarksSupplier
->getBookmarks()->getByName("replacement"), uno::UNO_QUERY
);
625 uno::Reference
<text::XTextRange
> xRange
= xTextContent
->getAnchor();
626 uno::Reference
<text::XTextCursor
> xCursor
627 = xRange
->getText()->createTextCursorByRange(xRange
);
628 CPPUNIT_ASSERT(!xCursor
->isCollapsed());
630 // Verify bookmark content via text node / PaM
631 auto mark
= *(rIDMA
.getBookmarksBegin());
632 CPPUNIT_ASSERT(mark
->IsExpanded());
633 SwPaM
pam(mark
->GetMarkStart(), mark
->GetMarkEnd());
634 CPPUNIT_ASSERT_EQUAL(emptyInputTextField
, pam
.GetText());
638 // If you resave original document the bookmark will be changed from
640 // <text:p text:style-name="Standard">
641 // <text:bookmark-start text:name="test"/>
642 // <text:bookmark-end text:name="test"/>
648 // <text:p text:style-name="Standard">
649 // <text:bookmark text:name="test"/>
653 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testBookmarkCollapsed
)
656 createSwDoc("collapsed_bookmark.odt");
657 SwDoc
* pDoc
= getSwDoc();
658 CPPUNIT_ASSERT(pDoc
);
660 // save original document
663 // load only content.xml from the resaved document
664 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
666 const OString
aPath("/office:document-content/office:body/office:text/text:p");
668 const int pos1
= getXPathPosition(pXmlDoc
, aPath
, "bookmark");
669 CPPUNIT_ASSERT_EQUAL(0, pos1
); // found, and it is first
671 CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pXmlDoc
, aPath
, "bookmark-start")); // not found
672 CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pXmlDoc
, aPath
, "bookmark-end")); // not found
675 // 1. Open a new writer document
676 // 2. Enter the text "abcdef"
678 // 4. Insert a bookmark on "abc" using Insert->Bookmark. Name the bookmark "test".
679 // 5. Open the navigator (F5)
680 // Select the bookmark "test" using the navigator.
681 // 6. Hit Del, thus deleting "abc" (The bookmark "test" is still there).
682 // 7. Save the document:
683 // <text:p text:style-name="Standard">
684 // <text:bookmark-start text:name="test"/>
685 // <text:bookmark-end text:name="test"/>
689 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testRemoveBookmarkText
)
693 // create a text document with "abcdef"
695 SwDoc
* pDoc
= getSwDoc();
698 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
700 pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "abcdef");
703 // mark "abc" with "testBookmark" bookmark
705 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
708 lcl_selectCharacters(aPaM
, 0, 3);
709 IDocumentMarkAccess
& rIDMA
= *pDoc
->getIDocumentMarkAccess();
710 sw::mark::IMark
* pMark
711 = rIDMA
.makeMark(aPaM
, "testBookmark", IDocumentMarkAccess::MarkType::BOOKMARK
,
712 ::sw::mark::InsertMode::New
);
715 CPPUNIT_ASSERT(pMark
->IsExpanded());
716 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getBookmarksCount());
719 // remove text marked with bookmark
721 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
724 lcl_selectCharacters(aPaM
, 0, 3);
725 pDoc
->getIDocumentContentOperations().DeleteRange(aPaM
);
727 // verify: bookmark is still exist
728 IDocumentMarkAccess
& rIDMA
= *pDoc
->getIDocumentMarkAccess();
729 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getBookmarksCount());
736 // load only content.xml from the resaved document
737 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
739 const OString
aPath("/office:document-content/office:body/office:text/text:p");
741 CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pXmlDoc
, aPath
, "bookmark")); // not found
742 const int pos2
= getXPathPosition(pXmlDoc
, aPath
, "bookmark-start");
743 const int pos3
= getXPathPosition(pXmlDoc
, aPath
, "bookmark-end");
745 CPPUNIT_ASSERT_EQUAL(0, pos2
); // found, and it is first
746 CPPUNIT_ASSERT_EQUAL(1, pos3
); // found, and it is second
749 // 1. Open a new writer document
750 // 2. Enter the text "abcdef"
752 // 4. Insert a bookmark on "abc" using Insert->Bookmark. Name the bookmark "test".
753 // 5. Open the navigator (F5)
754 // Select the bookmark "test" using the navigator.
755 // 6. Hit Del, thus deleting "abc" (The bookmark "test" is still there).
759 // bookmark = ThisComponent.getBookmarks().getByName("test")
760 // bookmark.getAnchor().setString("abc")
763 // The text "abc" gets inserted inside the bookmark "test", and the document now contains the string "abcdef".
764 // 7. Save the document:
765 // <text:p text:style-name="Standard">
766 // <text:bookmark-start text:name="test"/>
768 // <text:bookmark-end text:name="test"/>
772 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testRemoveBookmarkTextAndAddNew
)
776 // create a text document with "abcdef"
778 SwDoc
* pDoc
= getSwDoc();
780 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
782 pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "abcdef");
785 // mark "abc" with "testBookmark" bookmark
787 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
790 lcl_selectCharacters(aPaM
, 0, 3);
791 IDocumentMarkAccess
& rIDMA
= *pDoc
->getIDocumentMarkAccess();
792 sw::mark::IMark
* pMark
793 = rIDMA
.makeMark(aPaM
, "testBookmark", IDocumentMarkAccess::MarkType::BOOKMARK
,
794 ::sw::mark::InsertMode::New
);
797 CPPUNIT_ASSERT(pMark
->IsExpanded());
798 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getBookmarksCount());
801 // remove text marked with bookmark
803 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
806 lcl_selectCharacters(aPaM
, 0, 3);
807 pDoc
->getIDocumentContentOperations().DeleteRange(aPaM
);
809 // verify: bookmark is still exist
810 IDocumentMarkAccess
& rIDMA
= *pDoc
->getIDocumentMarkAccess();
811 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getBookmarksCount());
814 // write "abc" to area marked with "testBookmark" bookmark
816 // Get helper objects
817 uno::Reference
<text::XBookmarksSupplier
> xBookmarksSupplier(mxComponent
,
820 // Create cursor from bookmark
821 uno::Reference
<text::XTextContent
> xTextContent(
822 xBookmarksSupplier
->getBookmarks()->getByName("testBookmark"), uno::UNO_QUERY
);
823 uno::Reference
<text::XTextRange
> xRange
= xTextContent
->getAnchor();
824 CPPUNIT_ASSERT_EQUAL(OUString(""), xRange
->getString());
827 xRange
->setString("abc");
829 // verify: bookmark is still exist
830 IDocumentMarkAccess
& rIDMA
= *pDoc
->getIDocumentMarkAccess();
831 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getBookmarksCount());
838 // load only content.xml from the resaved document
839 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
841 const OString
aPath("/office:document-content/office:body/office:text/text:p");
843 CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pXmlDoc
, aPath
, "bookmark")); // not found
844 const int pos2
= getXPathPosition(pXmlDoc
, aPath
, "bookmark-start");
845 const int pos3
= getXPathPosition(pXmlDoc
, aPath
, "text");
846 const int pos4
= getXPathPosition(pXmlDoc
, aPath
, "bookmark-end");
848 CPPUNIT_ASSERT_EQUAL(0, pos2
);
849 CPPUNIT_ASSERT_EQUAL(1, pos3
);
850 CPPUNIT_ASSERT_EQUAL(2, pos4
);
854 // <text:p text:style-name="Standard">
855 // <text:bookmark-start text:name="test"/>
856 // <text:bookmark-end text:name="test"/>
863 // bookmark = ThisComponent.getBookmarks().getByName("test")
864 // bookmark.getAnchor().setString("abc")
867 // The text "abc" gets inserted inside the bookmark "test", and the document now contains the string "abcdef".
868 // 3. Save the document:
869 // <text:p text:style-name="Standard">
870 // <text:bookmark text:name="test"/>
874 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testRemoveBookmarkTextAndAddNewAfterReload
)
877 createSwDoc("collapsed_bookmark.odt");
878 SwDoc
* pDoc
= getSwDoc();
879 CPPUNIT_ASSERT(pDoc
);
881 // write "abc" to area marked with "testBookmark" bookmark
883 // Get helper objects
884 uno::Reference
<text::XBookmarksSupplier
> xBookmarksSupplier(mxComponent
, uno::UNO_QUERY
);
886 // Create cursor from bookmark
887 uno::Reference
<text::XTextContent
> xTextContent(
888 xBookmarksSupplier
->getBookmarks()->getByName("test"), uno::UNO_QUERY
);
889 uno::Reference
<text::XTextRange
> xRange
= xTextContent
->getAnchor();
890 CPPUNIT_ASSERT_EQUAL(OUString(""), xRange
->getString());
893 xRange
->setString("abc");
895 // verify: bookmark is still exist
896 IDocumentMarkAccess
& rIDMA
= *pDoc
->getIDocumentMarkAccess();
897 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA
.getBookmarksCount());
900 // save original document
903 // load only content.xml from the resaved document
904 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
905 const OString
aPath("/office:document-content/office:body/office:text/text:p");
907 const int pos1
= getXPathPosition(pXmlDoc
, aPath
, "bookmark");
908 const int pos2
= getXPathPosition(pXmlDoc
, aPath
, "text");
910 CPPUNIT_ASSERT_EQUAL(0, pos1
);
911 CPPUNIT_ASSERT_EQUAL(1, pos2
);
913 CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pXmlDoc
, aPath
, "bookmark-start")); // not found
914 CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pXmlDoc
, aPath
, "bookmark-end")); // not found
917 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf96961
)
919 // Insert a page break.
921 SwDoc
* pDoc
= getSwDoc();
922 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
923 pWrtShell
->InsertPageBreak();
925 // Enable hide whitespace mode.
926 SwViewOption
aViewOptions(*pWrtShell
->GetViewOptions());
927 aViewOptions
.SetHideWhitespaceMode(true);
928 pWrtShell
->ApplyViewOptions(aViewOptions
);
932 // Assert that the height of the last page is larger than the height of other pages.
933 sal_Int32 nOther
= parseDump("/root/page[1]/infos/bounds", "height").toInt32();
934 sal_Int32 nLast
= parseDump("/root/page[2]/infos/bounds", "height").toInt32();
935 CPPUNIT_ASSERT(nLast
> nOther
);
938 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf88453
)
940 createSwDoc("tdf88453.odt");
942 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
943 // This was 0: the table does not fit the first page, but it wasn't split
944 // to continue on the second page.
945 assertXPath(pXmlDoc
, "/root/page[2]/body/tab", 1);
948 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf88453Table
)
950 createSwDoc("tdf88453-table.odt");
952 // This was 2: layout could not split the large outer table in the document
954 CPPUNIT_ASSERT_EQUAL(3, getPages());
959 int checkShells(const SwDocShell
* pSource
, const SwDocShell
* pDestination
)
961 return int(SfxClassificationHelper::CheckPaste(pSource
->getDocProperties(),
962 pDestination
->getDocProperties()));
966 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testClassificationPaste
)
969 SwDocShell
* pSourceShell
= getSwDoc()->GetDocShell();
970 uno::Reference
<lang::XComponent
> xSourceComponent
= mxComponent
;
974 SwDocShell
* pDestinationShell
= getSwDoc()->GetDocShell();
976 // Not classified source, not classified destination.
977 CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::None
),
978 checkShells(pSourceShell
, pDestinationShell
));
980 // Classified source, not classified destination.
981 uno::Sequence
<beans::PropertyValue
> aInternalOnly
982 = comphelper::InitPropertySequence({ { "Name", uno::Any(OUString("Internal Only")) } });
983 dispatchCommand(xSourceComponent
, ".uno:ClassificationApply", aInternalOnly
);
984 CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::TargetDocNotClassified
),
985 checkShells(pSourceShell
, pDestinationShell
));
987 // Classified source and classified destination -- internal only has a higher level than confidential.
988 uno::Sequence
<beans::PropertyValue
> aConfidential
989 = comphelper::InitPropertySequence({ { "Name", uno::Any(OUString("Confidential")) } });
990 dispatchCommand(mxComponent
, ".uno:ClassificationApply", aConfidential
);
991 CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::DocClassificationTooLow
),
992 checkShells(pSourceShell
, pDestinationShell
));
994 xSourceComponent
->dispose();
997 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testSmallCaps
)
999 // Create a document, add some characters and select them.
1002 SwDoc
* pDoc
= getSwDoc();
1003 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
1004 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
1005 pWrtShell
->Insert("text");
1006 pWrtShell
->SelAll();
1008 // Dispatch the command to make them formatted small capitals.
1009 dispatchCommand(mxComponent
, ".uno:SmallCaps", {});
1011 // This was css::style::CaseMap::NONE as the shell didn't handle the command.
1012 CPPUNIT_ASSERT_EQUAL(css::style::CaseMap::SMALLCAPS
,
1013 getProperty
<sal_Int16
>(getRun(getParagraph(1), 1), "CharCaseMap"));
1016 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf98987
)
1018 createSwDoc("tdf98987.docx");
1020 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1021 assertXPath(pXmlDoc
, "/root/page/body/txt/anchored/SwAnchoredDrawObject[2]/SdrObject", "name",
1023 sal_Int32 nRectangle1
1024 = getXPath(pXmlDoc
, "/root/page/body/txt/anchored/SwAnchoredDrawObject[2]/bounds", "top")
1026 assertXPath(pXmlDoc
, "/root/page/body/txt/anchored/SwAnchoredDrawObject[1]/SdrObject", "name",
1028 sal_Int32 nRectangle2
1029 = getXPath(pXmlDoc
, "/root/page/body/txt/anchored/SwAnchoredDrawObject[1]/bounds", "top")
1031 CPPUNIT_ASSERT_GREATER(nRectangle1
, nRectangle2
);
1033 assertXPath(pXmlDoc
, "/root/page/body/txt/anchored/SwAnchoredDrawObject[3]/SdrObject", "name",
1035 sal_Int32 nRectangle3
1036 = getXPath(pXmlDoc
, "/root/page/body/txt/anchored/SwAnchoredDrawObject[3]/bounds", "top")
1038 // This failed: the 3rd rectangle had a smaller "top" value than the 2nd one, it even overlapped with the 1st one.
1039 CPPUNIT_ASSERT_GREATER(nRectangle2
, nRectangle3
);
1042 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf99004
)
1044 createSwDoc("tdf99004.docx");
1046 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1047 sal_Int32 nTextbox1Top
1048 = getXPath(pXmlDoc
, "/root/page/body/txt/anchored/fly/infos/bounds", "top").toInt32();
1049 sal_Int32 nTextBox1Height
1050 = getXPath(pXmlDoc
, "/root/page/body/txt/anchored/fly/infos/bounds", "height").toInt32();
1051 sal_Int32 nTextBox1Bottom
= nTextbox1Top
+ nTextBox1Height
;
1053 assertXPath(pXmlDoc
, "/root/page/body/txt/anchored/SwAnchoredDrawObject[1]/SdrObject", "name",
1055 sal_Int32 nRectangle2Top
1056 = getXPath(pXmlDoc
, "/root/page/body/txt/anchored/SwAnchoredDrawObject[1]/bounds", "top")
1058 // This was 3291 and 2531, should be now around 2472 and 2531, i.e. the two rectangles should not overlap anymore.
1059 CPPUNIT_ASSERT(nTextBox1Bottom
< nRectangle2Top
);
1062 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf84695
)
1064 createSwDoc("tdf84695.odt");
1065 SwDoc
* pDoc
= getSwDoc();
1066 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
1067 SdrPage
* pPage
= pDoc
->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1068 SdrObject
* pObject
= pPage
->GetObj(1);
1069 SwContact
* pTextBox
= static_cast<SwContact
*>(pObject
->GetUserCall());
1070 // First, make sure that pTextBox is a fly frame (textbox of a shape).
1071 CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_FLYFRMFMT
), pTextBox
->GetFormat()->Which());
1074 pWrtShell
->SelectObj(Point(), 0, pObject
);
1076 // Now Enter + a key should add some text.
1077 SwXTextDocument
* pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
1078 CPPUNIT_ASSERT(pXTextDocument
);
1079 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_RETURN
);
1080 emulateTyping(*pXTextDocument
, u
"a");
1082 uno::Reference
<text::XTextRange
> xShape(getShape(1), uno::UNO_QUERY
);
1083 // This was empty, Enter did not start the fly frame edit mode.
1084 CPPUNIT_ASSERT_EQUAL(OUString("a"), xShape
->getString());
1087 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf84695NormalChar
)
1089 createSwDoc("tdf84695.odt");
1090 SwDoc
* pDoc
= getSwDoc();
1091 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
1092 SdrPage
* pPage
= pDoc
->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1093 SdrObject
* pObject
= pPage
->GetObj(1);
1094 SwContact
* pTextBox
= static_cast<SwContact
*>(pObject
->GetUserCall());
1095 // First, make sure that pTextBox is a fly frame (textbox of a shape).
1096 CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_FLYFRMFMT
), pTextBox
->GetFormat()->Which());
1099 pWrtShell
->SelectObj(Point(), 0, pObject
);
1101 // Now pressing 'a' should add a character.
1102 SwXTextDocument
* pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
1103 CPPUNIT_ASSERT(pXTextDocument
);
1104 emulateTyping(*pXTextDocument
, u
"a");
1106 uno::Reference
<text::XTextRange
> xShape(getShape(1), uno::UNO_QUERY
);
1107 // This was empty, pressing a normal character did not start the fly frame edit mode.
1108 CPPUNIT_ASSERT_EQUAL(OUString("a"), xShape
->getString());
1111 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf84695Tab
)
1113 createSwDoc("tdf84695-tab.odt");
1114 SwDoc
* pDoc
= getSwDoc();
1115 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
1116 SdrPage
* pPage
= pDoc
->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1117 SdrObject
* pObject
= pPage
->GetObj(0);
1118 SwContact
* pShape
= static_cast<SwContact
*>(pObject
->GetUserCall());
1119 // First, make sure that pShape is a draw shape.
1120 CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_DRAWFRMFMT
), pShape
->GetFormat()->Which());
1123 pWrtShell
->SelectObj(Point(), 0, pObject
);
1125 // Now pressing 'tab' should jump to the other shape.
1126 SwXTextDocument
* pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
1127 CPPUNIT_ASSERT(pXTextDocument
);
1128 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
1129 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_TAB
);
1130 Scheduler::ProcessEventsToIdle();
1132 // And finally make sure the selection has changed.
1133 const SdrMarkList
& rMarkList
= pWrtShell
->GetDrawView()->GetMarkedObjectList();
1134 SwContact
* pOtherShape
1135 = static_cast<SwContact
*>(rMarkList
.GetMark(0)->GetMarkedSdrObj()->GetUserCall());
1136 // This failed, 'tab' didn't do anything -> the selected shape was the same.
1137 CPPUNIT_ASSERT(pOtherShape
!= pShape
);
1140 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTableStyleUndo
)
1143 SwDoc
* pDoc
= getSwDoc();
1144 sw::UndoManager
& rUndoManager
= pDoc
->GetUndoManager();
1146 sal_Int32 nStyleCount
= pDoc
->GetTableStyles().size();
1147 SwTableAutoFormat
* pStyle
= pDoc
->MakeTableStyle("Test Style");
1148 SvxBrushItem
aBackground(Color(0xFF00FF), RES_BACKGROUND
);
1149 pStyle
->GetBoxFormat(0).SetBackground(aBackground
);
1151 CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc
->GetTableStyles().size()), nStyleCount
+ 1);
1152 rUndoManager
.Undo();
1153 CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc
->GetTableStyles().size()), nStyleCount
);
1154 rUndoManager
.Redo();
1155 CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc
->GetTableStyles().size()), nStyleCount
+ 1);
1156 // check if attributes are preserved
1157 pStyle
= pDoc
->GetTableStyles().FindAutoFormat(u
"Test Style");
1158 CPPUNIT_ASSERT(pStyle
);
1159 CPPUNIT_ASSERT(bool(pStyle
->GetBoxFormat(0).GetBackground() == aBackground
));
1161 pDoc
->DelTableStyle("Test Style");
1162 CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc
->GetTableStyles().size()), nStyleCount
);
1163 rUndoManager
.Undo();
1164 CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc
->GetTableStyles().size()), nStyleCount
+ 1);
1165 pStyle
= pDoc
->GetTableStyles().FindAutoFormat(u
"Test Style");
1166 // check if attributes are preserved
1167 CPPUNIT_ASSERT(pStyle
);
1168 CPPUNIT_ASSERT(bool(pStyle
->GetBoxFormat(0).GetBackground() == aBackground
));
1169 rUndoManager
.Redo();
1170 CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc
->GetTableStyles().size()), nStyleCount
);
1172 // undo delete so we can replace the style
1173 rUndoManager
.Undo();
1174 CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc
->GetTableStyles().size()), nStyleCount
+ 1);
1175 pStyle
= pDoc
->GetTableStyles().FindAutoFormat(u
"Test Style");
1176 CPPUNIT_ASSERT(pStyle
);
1177 CPPUNIT_ASSERT(bool(pStyle
->GetBoxFormat(0).GetBackground() == aBackground
));
1179 SwTableAutoFormat
aNewStyle("Test Style2");
1180 SvxBrushItem
aBackground2(Color(0x00FF00), RES_BACKGROUND
);
1181 aNewStyle
.GetBoxFormat(0).SetBackground(aBackground2
);
1183 pDoc
->ChgTableStyle("Test Style", aNewStyle
);
1184 pStyle
= pDoc
->GetTableStyles().FindAutoFormat(u
"Test Style");
1185 CPPUNIT_ASSERT(pStyle
);
1186 CPPUNIT_ASSERT(bool(pStyle
->GetBoxFormat(0).GetBackground() == aBackground2
));
1187 rUndoManager
.Undo();
1188 pStyle
= pDoc
->GetTableStyles().FindAutoFormat(u
"Test Style");
1189 CPPUNIT_ASSERT(pStyle
);
1190 CPPUNIT_ASSERT(bool(pStyle
->GetBoxFormat(0).GetBackground() == aBackground
));
1191 rUndoManager
.Redo();
1192 pStyle
= pDoc
->GetTableStyles().FindAutoFormat(u
"Test Style");
1193 CPPUNIT_ASSERT(pStyle
);
1194 CPPUNIT_ASSERT(bool(pStyle
->GetBoxFormat(0).GetBackground() == aBackground2
));
1197 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testRedlineCopyPaste
)
1199 // regressed in tdf#106746
1201 SwDoc
* pDoc
= getSwDoc();
1203 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
1206 pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "abzdezgh");
1207 SwTextNode
* pTextNode
= aPaM
.GetPointNode().GetTextNode();
1209 // Turn on track changes, make changes, turn off track changes
1210 uno::Reference
<beans::XPropertySet
> xPropertySet(mxComponent
, uno::UNO_QUERY
);
1211 xPropertySet
->setPropertyValue("RecordChanges", uno::Any(true));
1212 lcl_selectCharacters(aPaM
, 2, 3);
1213 pDoc
->getIDocumentContentOperations().ReplaceRange(aPaM
, "c", false);
1214 lcl_selectCharacters(aPaM
, 6, 7);
1215 pDoc
->getIDocumentContentOperations().ReplaceRange(aPaM
, "f", false);
1216 xPropertySet
->setPropertyValue("RecordChanges", uno::Any(false));
1218 // Create the clipboard document.
1220 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
1222 // Select the whole content, copy, delete the original and paste the copied content
1223 pWrtShell
->SelAll();
1224 pWrtShell
->Copy(aClipboard
);
1225 pWrtShell
->Delete();
1226 pWrtShell
->Paste(aClipboard
);
1228 // With the bug this is "abzcdefgh", ie. contains the first deleted piece, too
1229 CPPUNIT_ASSERT_EQUAL(OUString("abcdefgh"), pTextNode
->GetText());
1232 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf135260
)
1235 SwDoc
* pDoc
= getSwDoc();
1236 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
1237 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
1238 pWrtShell
->Insert("test");
1240 // Turn on track changes
1241 uno::Reference
<beans::XPropertySet
> xPropertySet(mxComponent
, uno::UNO_QUERY
);
1242 xPropertySet
->setPropertyValue("RecordChanges", uno::Any(true));
1244 for (int i
= 0; i
< 4; i
++)
1246 pWrtShell
->DelLeft();
1249 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
1250 // accept all redlines
1251 while (pEditShell
->GetRedlineCount())
1252 pEditShell
->AcceptRedline(0);
1254 // Without the fix in place, this test would have failed with
1257 CPPUNIT_ASSERT_EQUAL(OUString(""), getParagraph(1)->getString());
1260 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testRedlineParam
)
1262 // Create a document with minimal content.
1264 SwDoc
* pDoc
= getSwDoc();
1265 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
1266 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
1267 pWrtShell
->Insert("middle");
1269 // Turn on track changes, and add changes to the start and end of the document.
1270 uno::Reference
<beans::XPropertySet
> xPropertySet(mxComponent
, uno::UNO_QUERY
);
1271 xPropertySet
->setPropertyValue("RecordChanges", uno::Any(true));
1272 pWrtShell
->StartOfSection();
1273 pWrtShell
->Insert("aaa");
1274 pWrtShell
->EndOfSection();
1275 pWrtShell
->Insert("zzz");
1277 const SwRedlineTable
& rTable
= pDoc
->getIDocumentRedlineAccess().GetRedlineTable();
1278 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(2), rTable
.size());
1280 // Select the first redline.
1281 pWrtShell
->StartOfSection();
1282 uno::Sequence
<beans::PropertyValue
> aPropertyValues(comphelper::InitPropertySequence(
1283 { { "NextTrackedChange", uno::Any(o3tl::narrowing
<sal_uInt16
>(rTable
[0]->GetId())) } }));
1284 dispatchCommand(mxComponent
, ".uno:NextTrackedChange", aPropertyValues
);
1285 SwShellCursor
* pShellCursor
= pWrtShell
->getShellCursor(false);
1286 // This failed: the parameter wasn't handled so the next change (zzz) was
1287 // selected, not the first one (aaa).
1288 CPPUNIT_ASSERT_EQUAL(OUString("aaa"), pShellCursor
->GetText());
1290 // Select the second redline.
1291 pWrtShell
->StartOfSection();
1292 aPropertyValues
= comphelper::InitPropertySequence(
1293 { { "NextTrackedChange", uno::Any(o3tl::narrowing
<sal_uInt16
>(rTable
[1]->GetId())) } });
1294 dispatchCommand(mxComponent
, ".uno:NextTrackedChange", aPropertyValues
);
1295 pShellCursor
= pWrtShell
->getShellCursor(false);
1296 CPPUNIT_ASSERT_EQUAL(OUString("zzz"), pShellCursor
->GetText());
1298 // Move the cursor to the start again, and reject the second change.
1299 pWrtShell
->StartOfSection();
1300 aPropertyValues
= comphelper::InitPropertySequence(
1301 { { "RejectTrackedChange", uno::Any(o3tl::narrowing
<sal_uInt16
>(rTable
[1]->GetId())) } });
1302 dispatchCommand(mxComponent
, ".uno:RejectTrackedChange", aPropertyValues
);
1303 pShellCursor
= pWrtShell
->getShellCursor(false);
1305 // This was 'middlezzz', the uno command rejected the redline under the
1306 // cursor, instead of the requested one.
1307 CPPUNIT_ASSERT_EQUAL(OUString("aaamiddle"),
1308 pShellCursor
->GetPoint()->GetNode().GetTextNode()->GetText());
1311 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testRedlineViewAuthor
)
1313 // Test that setting an author at an SwView level has effect.
1315 // Create a document with minimal content.
1317 SwDoc
* pDoc
= getSwDoc();
1318 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
1319 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
1320 pWrtShell
->Insert("middle");
1321 SwView
* pView
= pDocShell
->GetView();
1322 const OUString
aAuthor("A U. Thor");
1323 pView
->SetRedlineAuthor(aAuthor
);
1324 pDocShell
->SetView(pView
);
1326 // Turn on track changes, and add changes to the start of the document.
1327 uno::Reference
<beans::XPropertySet
> xPropertySet(mxComponent
, uno::UNO_QUERY
);
1328 xPropertySet
->setPropertyValue("RecordChanges", uno::Any(true));
1329 pWrtShell
->StartOfSection();
1330 pWrtShell
->Insert("aaa");
1332 // Now assert that SwView::SetRedlineAuthor() had an effect.
1333 const SwRedlineTable
& rTable
= pDoc
->getIDocumentRedlineAccess().GetRedlineTable();
1334 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), rTable
.size());
1335 SwRangeRedline
* pRedline
= rTable
[0];
1336 // This was 'Unknown Author' instead of 'A U. Thor'.
1337 CPPUNIT_ASSERT_EQUAL(aAuthor
, pRedline
->GetAuthorString());
1339 // Insert a comment and assert that SwView::SetRedlineAuthor() affects this as well.
1340 dispatchCommand(mxComponent
, ".uno:.uno:InsertAnnotation", {});
1341 uno::Reference
<text::XTextFieldsSupplier
> xTextFieldsSupplier(mxComponent
, uno::UNO_QUERY
);
1342 uno::Reference
<container::XEnumerationAccess
> xFieldsAccess(
1343 xTextFieldsSupplier
->getTextFields());
1344 uno::Reference
<container::XEnumeration
> xFields(xFieldsAccess
->createEnumeration());
1345 uno::Reference
<beans::XPropertySet
> xField(xFields
->nextElement(), uno::UNO_QUERY
);
1346 // This was 'Unknown Author' instead of 'A U. Thor'.
1347 CPPUNIT_ASSERT_EQUAL(aAuthor
, xField
->getPropertyValue("Author").get
<OUString
>());
1349 //Reset the redline author after using it, otherwise, it might interfere with other unittests
1350 pView
->SetRedlineAuthor("Unknown Author");
1351 pDocShell
->SetView(pView
);
1354 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf91292
)
1356 createSwDoc("tdf91292_paraBackground.docx");
1357 uno::Reference
<beans::XPropertySet
> xPropertySet(getParagraph(1), uno::UNO_QUERY
);
1358 CPPUNIT_ASSERT_EQUAL_MESSAGE("Solid background color", drawing::FillStyle_SOLID
,
1359 getProperty
<drawing::FillStyle
>(xPropertySet
, "FillStyle"));
1360 CPPUNIT_ASSERT_EQUAL_MESSAGE("Background Color", Color(0x5C2D91),
1361 getProperty
<Color
>(xPropertySet
, "FillColor"));
1363 // remove background color
1364 xPropertySet
->setPropertyValue("FillStyle", uno::Any(drawing::FillStyle_NONE
));
1366 // Save it and load it back.
1367 saveAndReload("Office Open XML Text");
1369 xPropertySet
.set(getParagraph(1), uno::UNO_QUERY
);
1370 CPPUNIT_ASSERT_EQUAL_MESSAGE("No background color", drawing::FillStyle_NONE
,
1371 getProperty
<drawing::FillStyle
>(xPropertySet
, "FillStyle"));
1374 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf78727
)
1376 createSwDoc("tdf78727.docx");
1377 SwDoc
* pDoc
= getSwDoc();
1378 SdrPage
* pPage
= pDoc
->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
1379 // This was 1: make sure we don't loose the TextBox anchored inside the
1380 // table that is moved inside a text frame.
1381 CPPUNIT_ASSERT(SwTextBoxHelper::getCount(pPage
) > 1);
1384 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testRedlineTimestamp
)
1386 // Test that a redline timestamp's second is not always 0.
1388 // Create a document with minimal content.
1390 SwDoc
* pDoc
= getSwDoc();
1391 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
1392 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
1393 pWrtShell
->Insert("middle");
1395 // Turn on track changes, and add changes to the start and to the end of
1397 uno::Reference
<beans::XPropertySet
> xPropertySet(mxComponent
, uno::UNO_QUERY
);
1398 xPropertySet
->setPropertyValue("RecordChanges", uno::Any(true));
1399 pWrtShell
->StartOfSection();
1400 pWrtShell
->Insert("aaa");
1401 osl::Thread::wait(std::chrono::seconds(1));
1402 pWrtShell
->EndOfSection();
1403 pWrtShell
->Insert("zzz");
1405 // Inserting additional characters at the start changed the table size to
1406 // 3, i.e. the first and the second "aaa" wasn't combined.
1407 pWrtShell
->StartOfSection();
1408 pWrtShell
->Insert("aaa");
1410 // Now assert that at least one of the seconds are not 0.
1411 const SwRedlineTable
& rTable
= pDoc
->getIDocumentRedlineAccess().GetRedlineTable();
1412 if (rTable
.size() >= 2
1413 && rTable
[0]->GetRedlineData().GetTimeStamp().GetMin()
1414 != rTable
[1]->GetRedlineData().GetTimeStamp().GetMin())
1415 // The relatively rare case when waiting for a second also changes the minute.
1418 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(2), rTable
.size());
1419 sal_uInt16 nSec1
= rTable
[0]->GetRedlineData().GetTimeStamp().GetSec();
1420 sal_uInt16 nSec2
= rTable
[1]->GetRedlineData().GetTimeStamp().GetSec();
1421 // This failed, seconds was always 0.
1422 CPPUNIT_ASSERT(nSec1
!= 0 || nSec2
!= 0);
1425 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testCursorWindows
)
1427 // Create a new document with one window.
1429 SwDoc
* pDoc
= getSwDoc();
1430 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
1431 SwWrtShell
* pWrtShell1
= pDocShell
->GetWrtShell();
1433 // Create a second view and type something.
1434 pDocShell
->GetViewShell()->GetViewFrame().GetDispatcher()->Execute(
1435 SID_NEWWINDOW
, SfxCallMode::SYNCHRON
| SfxCallMode::RECORD
);
1436 SwWrtShell
* pWrtShell2
= pDocShell
->GetWrtShell();
1437 OUString
aText("foo");
1438 pWrtShell2
->Insert(aText
);
1440 // Assert that only the cursor of the actual window move, not other cursors.
1441 SwShellCursor
* pShellCursor1
= pWrtShell1
->getShellCursor(false);
1442 SwShellCursor
* pShellCursor2
= pWrtShell2
->getShellCursor(false);
1443 // This was 3, not 0 -- cursor of the other window moved.
1444 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0), pShellCursor1
->Start()->GetContentIndex());
1445 CPPUNIT_ASSERT_EQUAL(aText
.getLength(), pShellCursor2
->Start()->GetContentIndex());
1448 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testLandscape
)
1450 // Set page orientation to landscape.
1452 SwDoc
* pDoc
= getSwDoc();
1453 uno::Sequence
<beans::PropertyValue
> aPropertyValues(
1454 comphelper::InitPropertySequence({ { "AttributePage.Landscape", uno::Any(true) } }));
1455 dispatchCommand(mxComponent
, ".uno:AttributePage", aPropertyValues
);
1457 // Assert that the document model was modified.
1458 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
1459 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
1460 size_t nPageDesc
= pWrtShell
->GetCurPageDesc();
1461 // This failed, page was still portrait.
1462 CPPUNIT_ASSERT(pWrtShell
->GetPageDesc(nPageDesc
).GetLandscape());
1465 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf95699
)
1467 // Open the document with single FORMCHECKBOX field, select all and copy to clipboard
1468 // then check that clipboard contains the FORMCHECKBOX in text body.
1469 // Previously that failed.
1470 createSwDoc("tdf95699.odt");
1471 SwDoc
* pDoc
= getSwDoc();
1472 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
1473 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
1475 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
1476 pWrtShell
->SelAll();
1477 pWrtShell
->Copy(aClipboard
);
1478 pMarkAccess
= aClipboard
.getIDocumentMarkAccess();
1479 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess
->getAllMarksCount());
1480 ::sw::mark::IFieldmark
* pFieldMark
1481 = pMarkAccess
->getFieldmarkAfter(SwPosition(aClipboard
.GetNodes().GetEndOfExtras()), false);
1482 CPPUNIT_ASSERT_EQUAL(OUString("vnd.oasis.opendocument.field.FORMCHECKBOX"),
1483 pFieldMark
->GetFieldname());
1486 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf151548_tabNavigation2
)
1488 // given a form-protected doc with 2 unchecked legacy fieldmark checkboxes, 1 modern
1489 // checkbox, and a couple of other content controls that are not supposed to
1490 // have their contents selected upon entry into the control (i.e. no placeholder text).
1491 createSwDoc("tdf151548_tabNavigation2.docx");
1492 SwDoc
* pDoc
= getSwDoc();
1493 SwXTextDocument
* pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
1495 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
1496 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess
->getFieldmarksCount());
1498 // verify that the checkboxes start off in the unchecked state
1499 for (auto it
= pMarkAccess
->getFieldmarksBegin(); it
!= pMarkAccess
->getFieldmarksEnd(); ++it
)
1501 sw::mark::ICheckboxFieldmark
* pCheckBox
1502 = dynamic_cast<::sw::mark::ICheckboxFieldmark
*>(*it
);
1503 CPPUNIT_ASSERT(!pCheckBox
->IsChecked());
1506 // Toggle on the legacy checkbox
1507 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 32, KEY_SPACE
);
1508 // Tab to the next control - the modern checkbox
1509 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
1510 // Tab to the next control - the second legacy checkbox, and toggle it on.
1511 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
1512 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 32, KEY_SPACE
);
1513 // Tab to the next control - a plain text control without placeholder text
1514 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
1515 // Tab to the next control - a combobox with custom text
1516 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
1517 Scheduler::ProcessEventsToIdle();
1519 for (auto it
= pMarkAccess
->getFieldmarksBegin(); it
!= pMarkAccess
->getFieldmarksEnd(); ++it
)
1521 sw::mark::ICheckboxFieldmark
* pCheckBox
1522 = dynamic_cast<::sw::mark::ICheckboxFieldmark
*>(*it
);
1523 // verify that the legacy checkbox became checked by the first loop.
1524 CPPUNIT_ASSERT(pCheckBox
->IsChecked());
1526 // This is where it was failing. Tab got stuck moving into the plain text/combobox,
1527 // so it could never loop around. At this point we are at the end of the loop,
1528 // so the next tab should take us back to the beginning with the first legacy checkbox.
1530 // Tab to the legacy checkbox, and toggle it off.
1531 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
1532 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 32, KEY_SPACE
);
1533 Scheduler::ProcessEventsToIdle();
1534 CPPUNIT_ASSERT(!pCheckBox
->IsChecked());
1536 // Tab to the next content control
1537 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
1541 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf151548_tabNavigation
)
1543 // given a form-protected doc with 4 unchecked legacy fieldmark checkboxes (and several modern
1544 // content controls which all have a tabstop of -1 to disable tabstop navigation to them)
1545 // we want to test that tab navigation completes and loops around to continue at the beginning.
1546 createSwDoc("tdf151548_tabNavigation.docm");
1547 SwDoc
* pDoc
= getSwDoc();
1548 SwXTextDocument
* pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
1550 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
1551 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMarkAccess
->getFieldmarksCount());
1553 // Tab and toggle 4 times, verifying beforehand that the state was unchecked
1554 for (auto it
= pMarkAccess
->getFieldmarksBegin(); it
!= pMarkAccess
->getFieldmarksEnd(); ++it
)
1556 sw::mark::ICheckboxFieldmark
* pCheckBox
1557 = dynamic_cast<::sw::mark::ICheckboxFieldmark
*>(*it
);
1558 CPPUNIT_ASSERT(!pCheckBox
->IsChecked());
1560 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 32, KEY_SPACE
); // toggle checkbox on
1561 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
); // move to next control
1562 Scheduler::ProcessEventsToIdle();
1565 // Tab 4 more times, verifying beforehand that the checkbox had been toggle on, then toggles off
1566 // meaning that looping is working, and no other controls are reacting to the tab key.
1567 for (auto it
= pMarkAccess
->getFieldmarksBegin(); it
!= pMarkAccess
->getFieldmarksEnd(); ++it
)
1569 sw::mark::ICheckboxFieldmark
* pCheckBox
1570 = dynamic_cast<::sw::mark::ICheckboxFieldmark
*>(*it
);
1572 CPPUNIT_ASSERT(pCheckBox
->IsChecked());
1573 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 32, KEY_SPACE
); // toggle checkbox off
1574 Scheduler::ProcessEventsToIdle();
1576 CPPUNIT_ASSERT(!pCheckBox
->IsChecked());
1577 pXTextDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
); // move to next control
1581 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf104032
)
1583 // Open the document with FORMCHECKBOX field, select it and copy to clipboard
1584 // Go to end of document and paste it, then undo
1585 // Previously that asserted in debug build.
1586 createSwDoc("tdf104032.odt");
1587 SwDoc
* pDoc
= getSwDoc();
1588 sw::UndoManager
& rUndoManager
= pDoc
->GetUndoManager();
1590 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
1591 pWrtShell
->StartOfSection();
1592 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1593 pWrtShell
->Copy(aClipboard
);
1594 pWrtShell
->EndOfSection();
1595 pWrtShell
->Paste(aClipboard
);
1596 rUndoManager
.Undo();
1599 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf104440
)
1601 createSwDoc("tdf104440.odt");
1602 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1603 // This was 0: both Text Frames in the document were anchored to a
1604 // paragraph on page 1, while we expect that the second Text Frame is
1605 // anchored to a paragraph on page 2.
1606 assertXPath(pXmlDoc
, "//page[2]/body/txt/anchored");
1609 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf104425
)
1611 createSwDoc("tdf104425.odt");
1612 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1613 // The document contains one top-level 1-cell table with minimum row height set to 70 cm,
1614 // and the cell contents does not exceed the minimum row height.
1615 // It should span over 3 pages.
1616 assertXPath(pXmlDoc
, "//page", 3);
1618 = getXPath(pXmlDoc
, "//page[1]/body/tab/row/infos/bounds", "height").toInt32();
1620 = getXPath(pXmlDoc
, "//page[2]/body/tab/row/infos/bounds", "height").toInt32();
1622 = getXPath(pXmlDoc
, "//page[3]/body/tab/row/infos/bounds", "height").toInt32();
1623 double fSumHeight_mm
= o3tl::convert
<double>(nHeight1
+ nHeight2
+ nHeight3
, o3tl::Length::twip
,
1625 CPPUNIT_ASSERT_DOUBLES_EQUAL(700.0, fSumHeight_mm
, 0.05);
1628 // accepting change tracking gets stuck on change
1629 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf104814
)
1631 createSwDoc("tdf104814.docx");
1632 SwDoc
* pDoc1
= getSwDoc();
1634 SwEditShell
* const pEditShell(pDoc1
->GetEditShell());
1636 // accept all redlines
1637 while (pEditShell
->GetRedlineCount())
1638 pEditShell
->AcceptRedline(0);
1641 // crash at redo of accepting table change tracking imported from DOCX
1642 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTableRedlineRedoCrash
)
1644 createSwDoc("TC-table-del-add.docx");
1645 SwDoc
* pDoc
= getSwDoc();
1646 sw::UndoManager
& rUndoManager
= pDoc
->GetUndoManager();
1648 // accept all redlines, Undo and accept all redlines again
1650 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
1651 rIDRA
.AcceptAllRedline(/*bAccept=*/true);
1653 rUndoManager
.Undo();
1655 // without the fix, it crashes
1656 rIDRA
.AcceptAllRedline(true);
1659 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTableRemoveHasTextChangesOnly
)
1661 createSwDoc("TC-table-del-add.docx");
1662 SwDoc
* pDoc
= getSwDoc();
1663 CPPUNIT_ASSERT(pDoc
);
1664 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
1665 CPPUNIT_ASSERT(pWrtShell
);
1667 // disable Record Changes
1668 dispatchCommand(mxComponent
, ".uno:TrackChanges", {});
1669 CPPUNIT_ASSERT_MESSAGE("redlining should be off",
1670 !pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1672 // 4 rows in Show Changes mode
1673 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1674 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1676 // Accepting tracked deletions results 3 rows
1677 IDocumentRedlineAccess
& rIDRA(pDoc
->getIDocumentRedlineAccess());
1678 rIDRA
.AcceptAllRedline(/*bAccept=*/true);
1679 Scheduler::ProcessEventsToIdle();
1680 discardDumpedLayout();
1681 pXmlDoc
= parseLayoutDump();
1682 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 3);
1684 // Undo: 4 rows again
1685 pDoc
->GetIDocumentUndoRedo().Undo();
1686 discardDumpedLayout();
1687 pXmlDoc
= parseLayoutDump();
1688 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1690 // Accepting again: 3 rows (Undo of HasTextChangesOnly is correct)
1691 rIDRA
.AcceptAllRedline(/*bAccept=*/true);
1692 Scheduler::ProcessEventsToIdle();
1693 discardDumpedLayout();
1694 pXmlDoc
= parseLayoutDump();
1695 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 3);
1697 // Undo: 4 rows again
1698 pDoc
->GetIDocumentUndoRedo().Undo();
1699 discardDumpedLayout();
1700 pXmlDoc
= parseLayoutDump();
1701 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1703 // Move the cursor after the redline, and insert some text without change tracking
1704 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1705 pWrtShell
->Insert("X");
1707 // Accepting again: 4 rows (extra text keeps the deleted row)
1708 rIDRA
.AcceptAllRedline(/*bAccept=*/true);
1709 Scheduler::ProcessEventsToIdle();
1710 discardDumpedLayout();
1711 pXmlDoc
= parseLayoutDump();
1712 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1714 // delete the extra text with change tracking:
1715 // this resulted tracked row deletion again, because of missing
1716 // removing of HasTextChangeOnly SwTabLine property at accepting deletions previously
1718 // disable Record Changes
1719 dispatchCommand(mxComponent
, ".uno:TrackChanges", {});
1720 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1721 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1723 dispatchCommand(mxComponent
, ".uno:SwBackSpace", {});
1724 rIDRA
.AcceptAllRedline(/*bAccept=*/true);
1725 Scheduler::ProcessEventsToIdle();
1726 discardDumpedLayout();
1727 pXmlDoc
= parseLayoutDump();
1729 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1732 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTableRemoveHasTextChangesOnly2
)
1734 createSwDoc("TC-table-del-add.docx");
1735 SwDoc
* pDoc
= getSwDoc();
1736 CPPUNIT_ASSERT(pDoc
);
1737 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
1738 CPPUNIT_ASSERT(pWrtShell
);
1740 // disable Record Changes
1741 dispatchCommand(mxComponent
, ".uno:TrackChanges", {});
1742 CPPUNIT_ASSERT_MESSAGE("redlining should be off",
1743 !pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1745 // check redline count
1746 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
1747 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(14), pEditShell
->GetRedlineCount());
1749 // 4 rows in Show Changes mode
1750 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1751 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1753 // Move the cursor to the tracked insertion, after the first redline to activate the
1754 // acception of the whole table row insertion with a single "Accept Change"
1755 pWrtShell
->Down(/*bSelect=*/false);
1756 pWrtShell
->Down(/*bSelect=*/false);
1757 pWrtShell
->Down(/*bSelect=*/false);
1758 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
1759 Scheduler::ProcessEventsToIdle();
1760 dispatchCommand(mxComponent
, ".uno:AcceptTrackedChange", {});
1761 discardDumpedLayout();
1762 pXmlDoc
= parseLayoutDump();
1763 // Accepting tracked insertion results still 4 rows, but less redlines
1764 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1765 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(11), pEditShell
->GetRedlineCount());
1767 // Undo: 4 rows again
1768 pDoc
->GetIDocumentUndoRedo().Undo();
1769 discardDumpedLayout();
1770 pXmlDoc
= parseLayoutDump();
1771 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1772 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(14), pEditShell
->GetRedlineCount());
1774 // To check Undo of HasTextChangesOnly reject the same row results 3 rows
1775 dispatchCommand(mxComponent
, ".uno:Escape", {});
1776 dispatchCommand(mxComponent
, ".uno:RejectTrackedChange", {});
1777 discardDumpedLayout();
1778 pXmlDoc
= parseLayoutDump();
1779 // This was 4 (lost HasTextChangesOnly)
1780 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 3);
1782 // Undo: 4 rows again
1783 pDoc
->GetIDocumentUndoRedo().Undo();
1784 discardDumpedLayout();
1785 pXmlDoc
= parseLayoutDump();
1786 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1787 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(14), pEditShell
->GetRedlineCount());
1790 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf147182_AcceptAllChangesInTableSelection
)
1792 createSwDoc("TC-table-del-add.docx");
1793 SwDoc
* pDoc
= getSwDoc();
1794 CPPUNIT_ASSERT(pDoc
);
1795 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
1796 CPPUNIT_ASSERT(pWrtShell
);
1798 // check redline count
1799 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
1800 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(14), pEditShell
->GetRedlineCount());
1802 // 4 rows in Show Changes mode
1803 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1804 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1806 // Select the first table to get a table selection
1807 dispatchCommand(mxComponent
, ".uno:SelectAll", {});
1808 dispatchCommand(mxComponent
, ".uno:SelectAll", {});
1809 dispatchCommand(mxComponent
, ".uno:AcceptTrackedChange", {});
1810 discardDumpedLayout();
1811 pXmlDoc
= parseLayoutDump();
1812 // Accepting tracked changes in the selected table results 3 rows
1813 // This was 4 (only text changes of the first selected cell were accepted)
1814 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 3);
1815 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(8), pEditShell
->GetRedlineCount());
1817 // Undo: 4 rows again
1818 pDoc
->GetIDocumentUndoRedo().Undo();
1819 discardDumpedLayout();
1820 pXmlDoc
= parseLayoutDump();
1821 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1822 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(14), pEditShell
->GetRedlineCount());
1824 // To check Undo of HasTextChangesOnly reject the same row results 3 rows
1825 dispatchCommand(mxComponent
, ".uno:Escape", {});
1826 dispatchCommand(mxComponent
, ".uno:SelectAll", {});
1827 dispatchCommand(mxComponent
, ".uno:SelectAll", {});
1828 dispatchCommand(mxComponent
, ".uno:RejectTrackedChange", {});
1829 discardDumpedLayout();
1830 pXmlDoc
= parseLayoutDump();
1831 // This was 4 (only text changes of the first selected cell were rejected)
1832 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 3);
1834 // Undo: 4 rows again
1835 pDoc
->GetIDocumentUndoRedo().Undo();
1836 discardDumpedLayout();
1837 pXmlDoc
= parseLayoutDump();
1838 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row", 4);
1839 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(14), pEditShell
->GetRedlineCount());
1842 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf66405
)
1844 // Imported formula should have zero margins
1845 createSwDoc("tdf66405.docx");
1846 uno::Reference
<text::XTextEmbeddedObjectsSupplier
> xEmbeddedObjectsSupplier(mxComponent
,
1848 uno::Reference
<container::XNameAccess
> xEmbeddedObjects
1849 = xEmbeddedObjectsSupplier
->getEmbeddedObjects();
1850 uno::Reference
<beans::XPropertySet
> xFormula
;
1851 xEmbeddedObjects
->getByName(xEmbeddedObjects
->getElementNames()[0]) >>= xFormula
;
1852 uno::Reference
<beans::XPropertySet
> xComponent
;
1853 xFormula
->getPropertyValue("Component") >>= xComponent
;
1855 // Test embedded object's margins
1856 sal_Int32 nLeftMargin
, nRightMargin
, nTopMargin
, nBottomMargin
;
1857 xFormula
->getPropertyValue("LeftMargin") >>= nLeftMargin
;
1858 xFormula
->getPropertyValue("RightMargin") >>= nRightMargin
;
1859 xFormula
->getPropertyValue("TopMargin") >>= nTopMargin
;
1860 xFormula
->getPropertyValue("BottomMargin") >>= nBottomMargin
;
1861 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nLeftMargin
);
1862 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nRightMargin
);
1863 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nTopMargin
);
1864 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nBottomMargin
);
1866 // Test embedded object component's margins
1867 xComponent
->getPropertyValue("LeftMargin") >>= nLeftMargin
;
1868 xComponent
->getPropertyValue("RightMargin") >>= nRightMargin
;
1869 xComponent
->getPropertyValue("TopMargin") >>= nTopMargin
;
1870 xComponent
->getPropertyValue("BottomMargin") >>= nBottomMargin
;
1871 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nLeftMargin
);
1872 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nRightMargin
);
1873 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nTopMargin
);
1874 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nBottomMargin
);
1877 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf35021_tabOverMarginDemo
)
1880 createSwDoc("tdf35021_tabOverMarginDemo.doc");
1882 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1883 // Tabs should go past the margin @ ~3381
1884 sal_Int32 nMargin
= getXPath(pXmlDoc
, "//body/txt[1]/infos/prtBounds", "width").toInt32();
1885 // left tab was 3381 because it got its own full line
1887 = getXPath(pXmlDoc
, "//SwFixPortion[@type='PortionType::TabLeft']", "width").toInt32();
1888 CPPUNIT_ASSERT_MESSAGE("Left Tab width is ~4479", nMargin
< nWidth
);
1889 // center tab was 842
1890 nWidth
= getXPath(pXmlDoc
, "//SwFixPortion[@type='PortionType::TabCenter']", "width").toInt32();
1891 CPPUNIT_ASSERT_MESSAGE("Center Tab width is ~3521", nMargin
< nWidth
);
1892 // right tab was probably the same as center tab.
1893 nWidth
= getXPath(pXmlDoc
, "//SwFixPortion[@type='PortionType::TabRight']", "width").toInt32();
1894 CPPUNIT_ASSERT_MESSAGE("Right Tab width is ~2907", sal_Int32(2500) < nWidth
);
1895 // decimal tab was 266
1897 = getXPath(pXmlDoc
, "//SwFixPortion[@type='PortionType::TabDecimal']", "width").toInt32();
1898 CPPUNIT_ASSERT_MESSAGE("Decimal Tab width is ~4096", nMargin
< nWidth
);
1902 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf106701_tabOverMarginAutotab
)
1904 createSwDoc("tdf106701_tabOverMarginAutotab.doc");
1906 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1907 // The right margin is ~3378
1908 sal_Int32 nRightMargin
= getXPath(pXmlDoc
, "//body/txt[1]/infos/prtBounds", "width").toInt32();
1909 // Automatic tabstops should never be affected by tabOverMargin compatibility
1910 // The 1st line's width previously was ~9506
1911 sal_Int32 nWidth
= getXPath(pXmlDoc
, "//SwParaPortion/SwLineLayout[1]", "width").toInt32();
1912 CPPUNIT_ASSERT_MESSAGE("1st line's width is less than the right margin", nWidth
< nRightMargin
);
1915 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf104492
)
1917 createSwDoc("tdf104492.docx");
1918 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1919 // The document should split table over 3 pages.
1920 assertXPath(pXmlDoc
, "//page", 3);
1923 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf107025
)
1925 // Tdf107025 - characters advance with wrong distance, so that
1926 // they are cluttered because of negative value or
1927 // break into multiple lines because of overflow.
1928 // The test document uses DFKAI-SB shipped with Windows.
1929 createSwDoc("tdf107025.odt");
1930 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1931 // Verify the number of characters in each line.
1932 CPPUNIT_ASSERT_EQUAL(sal_Int32(1),
1933 getXPath(pXmlDoc
, "(//SwLinePortion)[1]", "length").toInt32());
1934 CPPUNIT_ASSERT_EQUAL(sal_Int32(9),
1935 getXPath(pXmlDoc
, "(//SwLinePortion)[2]", "length").toInt32());
1937 // Do the subsequent test only if the first line can be displayed,
1938 // in case that the required font does not exist.
1939 sal_Int32 nWidth1
= getXPath(pXmlDoc
, "(//SwLinePortion)[1]", "width").toInt32();
1943 CPPUNIT_ASSERT(!parseDump("(//SwLinePortion)[2]", "width").isEmpty());
1944 sal_Int32 nWidth2
= getXPath(pXmlDoc
, "(//SwLinePortion)[2]", "width").toInt32();
1945 sal_Int32 nRatio
= nWidth2
/ nWidth1
;
1947 CPPUNIT_ASSERT(nRatio
>= 9); // Occupy at least 9 cells.
1948 CPPUNIT_ASSERT(nRatio
< 18); // Occupy at most 18 cells.
1951 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf107362
)
1953 createSwDoc("tdf107362.odt");
1954 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1956 = getXPath(pXmlDoc
, "(//SwParaPortion/SwLineLayout/child::*[@type='PortionType::Text'])[1]",
1960 = getXPath(pXmlDoc
, "(//SwParaPortion/SwLineLayout/child::*[@type='PortionType::Text'])[1]",
1964 = getXPath(pXmlDoc
, "(//SwParaPortion/SwLineLayout/child::*[@type='PortionType::Text'])[2]",
1967 sal_Int32 nLineWidth
= getXPath(pXmlDoc
, "//SwParaPortion/SwLineLayout", "width").toInt32();
1968 sal_Int32 nKernWidth
= nLineWidth
- nWidth1
- nWidth2
;
1969 // Test only if fonts are available
1970 if (nWidth1
> 500 && nWidth2
> 200)
1972 // Kern width should be smaller than 1/3 of the CJK font height.
1973 CPPUNIT_ASSERT(nKernWidth
* 3 < nHeight
);
1977 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf105417
)
1979 createSwDoc("tdf105417.odt");
1980 SwDoc
* pDoc
= getSwDoc();
1981 CPPUNIT_ASSERT(pDoc
);
1982 SwView
* pView
= pDoc
->GetDocShell()->GetView();
1983 CPPUNIT_ASSERT(pView
);
1984 uno::Reference
<linguistic2::XHyphenator
> xHyphenator
= LinguMgr::GetHyphenator();
1985 CPPUNIT_ASSERT(xHyphenator
.is());
1986 // If there are no English hyphenation rules installed, we can't test
1988 if (!xHyphenator
->hasLocale(lang::Locale("en", "US", OUString())))
1991 uno::Reference
<linguistic2::XLinguProperties
> xLinguProperties(LinguMgr::GetLinguPropertySet());
1992 // Automatic hyphenation means not opening a dialog, but going ahead
1993 // non-interactively.
1994 xLinguProperties
->setIsHyphAuto(true);
1995 SwHyphWrapper
aWrap(pView
, xHyphenator
, /*bStart=*/false, /*bOther=*/true,
1996 /*bSelection=*/false);
1997 // This never returned, it kept trying to hyphenate the last word
1998 // (greenbacks) again and again.
1999 aWrap
.SpellDocument();
2002 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf105625
)
2004 createSwDoc("tdf105625.fodt");
2005 SwDoc
* pDoc
= getSwDoc();
2006 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
2007 // Ensure correct initial setting
2008 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(
2009 comphelper::ConfigurationChanges::create());
2010 officecfg::Office::Writer::Cursor::Option::IgnoreProtectedArea::set(false, batch
);
2012 // We should be able to edit at positions adjacent to fields.
2013 // Check if the start and the end of the 1st paragraph are not protected
2014 // (they are adjacent to FORMCHECKBOX)
2015 pWrtShell
->SttPara();
2016 CPPUNIT_ASSERT_EQUAL(false, pWrtShell
->HasReadonlySel());
2017 pWrtShell
->EndPara();
2018 CPPUNIT_ASSERT_EQUAL(false, pWrtShell
->HasReadonlySel());
2019 // 2nd paragraph - FORMTEXT
2020 pWrtShell
->Down(/*bSelect=*/false);
2021 // Check selection across FORMTEXT field boundary - must be read-only
2022 pWrtShell
->SttPara();
2023 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
2024 CPPUNIT_ASSERT_EQUAL(true, pWrtShell
->HasReadonlySel());
2025 // Test deletion of whole field with single backspace
2026 // Previously it only removed right boundary of FORMTEXT, or failed removal at all
2027 const IDocumentMarkAccess
* pMarksAccess
= pDoc
->getIDocumentMarkAccess();
2028 sal_Int32 nMarksBefore
= pMarksAccess
->getAllMarksCount();
2029 pWrtShell
->EndPara();
2030 pWrtShell
->DelLeft();
2031 sal_Int32 nMarksAfter
= pMarksAccess
->getAllMarksCount();
2032 CPPUNIT_ASSERT_EQUAL(nMarksBefore
, nMarksAfter
+ 1);
2035 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf125151_protected
)
2037 // Similar to testTdf105625 except this is in a protected section,
2038 // so read-only is already true when fieldmarks are considered.
2039 createSwDoc("tdf125151_protected.fodt");
2040 SwDoc
* pDoc
= getSwDoc();
2041 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
2042 // Ensure correct initial setting
2043 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(
2044 comphelper::ConfigurationChanges::create());
2045 officecfg::Office::Writer::Cursor::Option::IgnoreProtectedArea::set(false, batch
);
2047 pWrtShell
->Down(/*bSelect=*/false);
2048 // The cursor moved inside of the FieldMark textbox.
2049 CPPUNIT_ASSERT_EQUAL_MESSAGE("Readonly 1", false, pWrtShell
->HasReadonlySel());
2050 // Move left to the start/definition of the textbox
2051 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
2052 CPPUNIT_ASSERT_EQUAL_MESSAGE("Readonly 2", true, pWrtShell
->HasReadonlySel());
2055 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf125151_protectedB
)
2057 // Similar to testTdf105625 except this is protected with the Protect_Form compat setting
2058 createSwDoc("tdf125151_protectedB.fodt");
2059 SwDoc
* pDoc
= getSwDoc();
2060 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
2061 // Ensure correct initial setting
2062 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(
2063 comphelper::ConfigurationChanges::create());
2064 officecfg::Office::Writer::Cursor::Option::IgnoreProtectedArea::set(false, batch
);
2066 // The cursor starts inside of the FieldMark textbox.
2067 CPPUNIT_ASSERT_EQUAL_MESSAGE("Readonly 1", false, pWrtShell
->HasReadonlySel());
2068 // Move left to the start/definition of the textbox
2069 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
2070 CPPUNIT_ASSERT_EQUAL_MESSAGE("Readonly 2", true, pWrtShell
->HasReadonlySel());
2073 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf106736
)
2075 createSwDoc("tdf106736-grid.odt");
2076 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
2079 "(//SwParaPortion/SwLineLayout/child::*[@type='PortionType::TabLeft'])[1]",
2082 // In tdf106736, width of tab overflow so that it got
2083 // width value around 9200, expected value is around 103
2084 CPPUNIT_ASSERT_MESSAGE("Left Tab width is ~103", nWidth
< 150);
2087 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testMsWordCompTrailingBlanks
)
2089 // The option is true in settings.xml
2090 createSwDoc("MsWordCompTrailingBlanksTrue.odt");
2091 SwDoc
* pDoc
= getSwDoc();
2092 CPPUNIT_ASSERT_EQUAL(true, pDoc
->getIDocumentSettingAccess().get(
2093 DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS
));
2095 // Check that trailing spaces spans have no width if option is enabled
2097 CPPUNIT_ASSERT_EQUAL(
2099 parseDump("/root/page/body/txt[2]/SwParaPortion/SwLineLayout/child::*[4]", "width"));
2100 CPPUNIT_ASSERT_EQUAL(
2102 parseDump("/root/page/body/txt[2]/SwParaPortion/SwLineLayout/child::*[5]", "width"));
2103 CPPUNIT_ASSERT_EQUAL(
2105 parseDump("/root/page/body/txt[3]/SwParaPortion/SwLineLayout/child::*[4]", "width"));
2106 CPPUNIT_ASSERT_EQUAL(
2108 parseDump("/root/page/body/txt[3]/SwParaPortion/SwLineLayout/child::*[5]", "width"));
2110 // The option is false in settings.xml
2111 createSwDoc("MsWordCompTrailingBlanksFalse.odt");
2113 CPPUNIT_ASSERT_EQUAL(false, pDoc
->getIDocumentSettingAccess().get(
2114 DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS
));
2116 // Check that trailing spaces spans have width if option is disabled
2118 parseDump("/root/page/body/txt[2]/SwParaPortion/SwLineLayout/child::*[4]", "width") != "0");
2120 parseDump("/root/page/body/txt[2]/SwParaPortion/SwLineLayout/child::*[5]", "width") != "0");
2122 parseDump("/root/page/body/txt[3]/SwParaPortion/SwLineLayout/child::*[4]", "width") != "0");
2124 parseDump("/root/page/body/txt[3]/SwParaPortion/SwLineLayout/child::*[5]", "width") != "0");
2126 // MsWordCompTrailingBlanks option should be false by default in new documents
2129 CPPUNIT_ASSERT_EQUAL(false, pDoc
->getIDocumentSettingAccess().get(
2130 DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS
));
2132 // The option should be true if a .docx, .doc or .rtf document is opened
2133 createSwDoc("MsWordCompTrailingBlanks.docx");
2135 CPPUNIT_ASSERT_EQUAL(true, pDoc
->getIDocumentSettingAccess().get(
2136 DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS
));
2139 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testCreateDocxAnnotation
)
2143 // insert an annotation with a text
2144 const OUString
aSomeText("some text");
2145 uno::Sequence
<beans::PropertyValue
> aPropertyValues
= comphelper::InitPropertySequence({
2146 { "Text", uno::Any(aSomeText
) },
2147 { "Author", uno::Any(OUString("me")) },
2149 dispatchCommand(mxComponent
, ".uno:InsertAnnotation", aPropertyValues
);
2151 // Save it as DOCX & load it again
2152 saveAndReload("Office Open XML Text");
2154 // get the annotation
2155 uno::Reference
<text::XTextFieldsSupplier
> xTextFieldsSupplier(mxComponent
, uno::UNO_QUERY
);
2156 uno::Reference
<container::XEnumerationAccess
> xFieldsAccess(
2157 xTextFieldsSupplier
->getTextFields());
2158 uno::Reference
<container::XEnumeration
> xFields(xFieldsAccess
->createEnumeration());
2159 uno::Reference
<beans::XPropertySet
> xField(xFields
->nextElement(), uno::UNO_QUERY
);
2161 // this was empty instead of "some text"
2162 CPPUNIT_ASSERT_EQUAL(aSomeText
, xField
->getPropertyValue("Content").get
<OUString
>());
2165 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf107976
)
2167 // Create a document and create two transferables.
2169 SwDoc
* pDoc
= getSwDoc();
2170 SwWrtShell
& rShell
= *pDoc
->GetDocShell()->GetWrtShell();
2171 rtl::Reference
<SwTransferable
> pTransferable(new SwTransferable(rShell
));
2172 rtl::Reference
<SwTransferable
> pTransferable2(new SwTransferable(rShell
));
2173 // Now close the document.
2174 mxComponent
->dispose();
2175 mxComponent
.clear();
2176 // This failed: the first shell had a pointer to the deleted shell.
2177 CPPUNIT_ASSERT(!pTransferable
->GetShell());
2178 CPPUNIT_ASSERT(!pTransferable2
->GetShell());
2181 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf58604
)
2184 // Allow linebreak character follows hanging punctuation immediately instead of
2185 // breaking at the start of the next line.
2186 createSwDoc("tdf58604.odt");
2187 CPPUNIT_ASSERT_EQUAL(
2188 OUString("PortionType::Break"),
2189 parseDump("(/root/page/body/txt/SwParaPortion/SwLineLayout[1]/child::*)[last()]", "type"));
2193 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf112025
)
2195 mergeDocs("fdo112025.odt", "fdo112025-insert.docx");
2197 CPPUNIT_ASSERT_EQUAL(3, getParagraphs());
2199 uno::Reference
<beans::XPropertySet
> xStyle(getStyles("PageStyles")->getByName("Standard"),
2201 CPPUNIT_ASSERT_EQUAL(true, getProperty
<bool>(xStyle
, "IsLandscape"));
2204 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf72942
)
2206 mergeDocs("fdo72942.docx", "fdo72942-insert.docx");
2208 // check styles of paragraphs added from [fdo72942.docx]
2209 const uno::Reference
<text::XTextRange
> xRun1
= getRun(getParagraph(1), 1);
2210 CPPUNIT_ASSERT_EQUAL(OUString("Default English (Liberation serif) text with "),
2211 xRun1
->getString());
2212 CPPUNIT_ASSERT_EQUAL(OUString("Liberation Serif"),
2213 getProperty
<OUString
>(xRun1
, "CharFontName"));
2215 const uno::Reference
<text::XTextRange
> xRun2
= getRun(getParagraph(2), 1);
2216 CPPUNIT_ASSERT_EQUAL(OUString("Header 1 English text (Liberation sans) with "),
2217 xRun2
->getString());
2218 CPPUNIT_ASSERT_EQUAL(OUString("Liberation Sans"), getProperty
<OUString
>(xRun2
, "CharFontName"));
2220 // check styles of paragraphs added from [fdo72942-insert.docx]
2221 const uno::Reference
<text::XTextRange
> xRun3
= getRun(getParagraph(4), 1);
2222 CPPUNIT_ASSERT_EQUAL(OUString("Default German text (Calibri) with "), xRun3
->getString());
2223 CPPUNIT_ASSERT_EQUAL(OUString("Liberation Serif"),
2224 getProperty
<OUString
>(xRun3
, "CharFontName"));
2226 const uno::Reference
<text::XTextRange
> xRun4
= getRun(getParagraph(5), 1);
2227 CPPUNIT_ASSERT_EQUAL(OUString("Header 1 German text (Calibri Light) with "),
2228 xRun4
->getString());
2229 CPPUNIT_ASSERT_EQUAL(OUString("Liberation Sans"), getProperty
<OUString
>(xRun4
, "CharFontName"));
2232 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf114306
)
2234 createSwDoc("fdo114306.odt");
2235 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
2237 // There are 2 long paragraphs in cell A1.
2238 // A part of paragraph 2 should flow over to the second page but
2239 // *not* the whole paragraph. There should be 2 paragraphs on
2240 // page 1 and 1 paragraph on page 2.
2241 assertXPath(pXmlDoc
, "/root/page[1]/body/tab[1]/row[1]/cell[1]/txt", 2);
2242 assertXPath(pXmlDoc
, "/root/page[2]/body/tab[1]/row[1]/cell[1]/txt", 1);
2245 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf114306_2
)
2247 // tdf#114306 fix unexpected page break in row-spanned table
2248 // load regression document without writer crash
2249 createSwDoc("fdo114306_2.odt");
2251 // correct number of pages
2252 CPPUNIT_ASSERT_EQUAL(4, getPages());
2255 // During insert of the document with list inside into the main document inside the list
2256 // we should merge both lists into one, when they have the same list properties
2257 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf113877
)
2259 mergeDocs("tdf113877_insert_numbered_list.odt", "tdf113877_insert_numbered_list.odt");
2261 const OUString listId1
= getProperty
<OUString
>(getParagraph(1), "ListId");
2262 const OUString listId4
= getProperty
<OUString
>(getParagraph(4), "ListId");
2263 const OUString listId5
= getProperty
<OUString
>(getParagraph(5), "ListId");
2264 const OUString listId6
= getProperty
<OUString
>(getParagraph(6), "ListId");
2265 const OUString listId7
= getProperty
<OUString
>(getParagraph(7), "ListId");
2267 // the initial list with 4 list items
2268 CPPUNIT_ASSERT_EQUAL(listId1
, listId4
);
2270 // the last of the first list, and the first of the inserted list
2271 CPPUNIT_ASSERT_EQUAL(listId4
, listId5
);
2272 CPPUNIT_ASSERT_EQUAL(listId5
, listId6
);
2273 CPPUNIT_ASSERT_EQUAL(listId6
, listId7
);
2276 // The same test as testTdf113877() but merging of two list should not be performed.
2277 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf113877NoMerge
)
2279 mergeDocs("tdf113877_insert_numbered_list.odt", "tdf113877_insert_numbered_list_abcd.odt");
2281 const OUString listId1
= getProperty
<OUString
>(getParagraph(1), "ListId");
2282 const OUString listId4
= getProperty
<OUString
>(getParagraph(4), "ListId");
2283 const OUString listId5
= getProperty
<OUString
>(getParagraph(5), "ListId");
2284 const OUString listId6
= getProperty
<OUString
>(getParagraph(6), "ListId");
2285 const OUString listId7
= getProperty
<OUString
>(getParagraph(7), "ListId");
2287 // the initial list with 4 list items
2288 CPPUNIT_ASSERT_EQUAL(listId1
, listId4
);
2290 // the last of the first list, and the first of the inserted list
2291 CPPUNIT_ASSERT(listId4
!= listId5
);
2292 CPPUNIT_ASSERT_EQUAL(listId5
, listId6
);
2293 CPPUNIT_ASSERT(listId6
!= listId7
);
2296 // Related test to testTdf113877(): Inserting into empty document a new document with list.
2297 // Insert position has NO its own paragraph style ("Standard" will be used).
2299 // Resulting document should be the same for following tests:
2300 // - testTdf113877_default_style()
2301 // - testTdf113877_Standard_style()
2303 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf113877_default_style
)
2305 mergeDocs(nullptr, "tdf113877_insert_numbered_list_abcd.odt");
2307 const OUString listId1
= getProperty
<OUString
>(getParagraph(1), "ListId");
2308 const OUString listId2
= getProperty
<OUString
>(getParagraph(2), "ListId");
2309 const OUString listId3
= getProperty
<OUString
>(getParagraph(3), "ListId");
2311 CPPUNIT_ASSERT_EQUAL(listId1
, listId2
);
2312 CPPUNIT_ASSERT_EQUAL(listId1
, listId3
);
2315 // Related test to testTdf113877(): Inserting into empty document a new document with list.
2316 // Insert position has its own paragraph style derived from "Standard", but this style is the same as "Standard".
2318 // Resulting document should be the same for following tests:
2319 // - testTdf113877_default_style()
2320 // - testTdf113877_Standard_style()
2322 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf113877_Standard_style
)
2324 mergeDocs("tdf113877_blank_ownStandard.odt", "tdf113877_insert_numbered_list_abcd.odt");
2326 const OUString listId1
= getProperty
<OUString
>(getParagraph(1), "ListId");
2327 const OUString listId2
= getProperty
<OUString
>(getParagraph(2), "ListId");
2328 const OUString listId3
= getProperty
<OUString
>(getParagraph(3), "ListId");
2330 CPPUNIT_ASSERT_EQUAL(listId1
, listId2
);
2331 CPPUNIT_ASSERT_EQUAL(listId1
, listId3
);
2334 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf113877_blank_bold_on
)
2336 mergeDocs("tdf113877_blank_bold_on.odt", "tdf113877_insert_numbered_list_abcd.odt");
2338 const OUString listId1
= getProperty
<OUString
>(getParagraph(1), "ListId");
2339 const OUString listId2
= getProperty
<OUString
>(getParagraph(2), "ListId");
2340 const OUString listId3
= getProperty
<OUString
>(getParagraph(3), "ListId");
2342 CPPUNIT_ASSERT_EQUAL(listId1
, listId2
);
2343 CPPUNIT_ASSERT_EQUAL(listId1
, listId3
);
2346 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf107975
)
2348 // This test also covers tdf#117185 tdf#110442
2350 createSwDoc("tdf107975.odt");
2351 SwXTextDocument
* pTextDoc
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
2353 uno::Reference
<text::XTextGraphicObjectsSupplier
> xTextGraphicObjectsSupplier(mxComponent
,
2355 uno::Reference
<container::XIndexAccess
> xIndexAccess(
2356 xTextGraphicObjectsSupplier
->getGraphicObjects(), uno::UNO_QUERY
);
2358 uno::Reference
<drawing::XShape
> xShape(xIndexAccess
->getByIndex(0), uno::UNO_QUERY
);
2360 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER
,
2361 getProperty
<text::TextContentAnchorType
>(xShape
, "AnchorType"));
2363 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess
->getCount());
2365 dispatchCommand(mxComponent
, ".uno:SelectAll", {});
2367 dispatchCommand(mxComponent
, ".uno:Copy", {});
2369 //Position the mouse cursor (caret) after "ABC" below the blue image
2370 dispatchCommand(mxComponent
, ".uno:GoRight", {});
2371 dispatchCommand(mxComponent
, ".uno:Paste", {});
2373 // without the fix, it crashes
2374 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess
->getCount());
2375 CPPUNIT_ASSERT_EQUAL(OUString("ABC"), getParagraph(1)->getString());
2376 dispatchCommand(mxComponent
, ".uno:Undo", {});
2377 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess
->getCount());
2378 dispatchCommand(mxComponent
, ".uno:Redo", {});
2379 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess
->getCount());
2380 dispatchCommand(mxComponent
, ".uno:Undo", {});
2381 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess
->getCount());
2382 dispatchCommand(mxComponent
, ".uno:Redo", {});
2383 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess
->getCount());
2384 dispatchCommand(mxComponent
, ".uno:Undo", {});
2385 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess
->getCount());
2387 //try again with anchor at start of doc which is another special case
2388 xShape
.set(xIndexAccess
->getByIndex(0), uno::UNO_QUERY
);
2389 uno::Reference
<text::XTextContent
> xShapeContent(xShape
, uno::UNO_QUERY
);
2390 uno::Reference
<text::XTextRange
> const xStart
= pTextDoc
->getText()->getStart();
2391 xShapeContent
->attach(xStart
);
2393 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER
,
2394 getProperty
<text::TextContentAnchorType
>(xShape
, "AnchorType"));
2396 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess
->getCount());
2398 dispatchCommand(mxComponent
, ".uno:SelectAll", {});
2400 dispatchCommand(mxComponent
, ".uno:Copy", {});
2402 //Position the mouse cursor (caret) after "ABC" below the blue image
2403 dispatchCommand(mxComponent
, ".uno:GoRight", {});
2404 dispatchCommand(mxComponent
, ".uno:Paste", {});
2406 // Fails quite a lot on multiple Jenkins slaves, but entirely reliably,
2408 // sw/qa/extras/uiwriter/uiwriter4.cxx(2407) : error : Assertion
2411 // i.e. the xIndexAccess->getCount() line.
2413 // without the fix, it crashes
2414 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess
->getCount());
2415 CPPUNIT_ASSERT_EQUAL(OUString("ABC"), getParagraph(1)->getString());
2416 dispatchCommand(mxComponent
, ".uno:Undo", {});
2417 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess
->getCount());
2418 dispatchCommand(mxComponent
, ".uno:Redo", {});
2419 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess
->getCount());
2420 dispatchCommand(mxComponent
, ".uno:Undo", {});
2421 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess
->getCount());
2422 dispatchCommand(mxComponent
, ".uno:Redo", {});
2423 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess
->getCount());
2424 dispatchCommand(mxComponent
, ".uno:Undo", {});
2425 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess
->getCount());
2429 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf113877_blank_bold_off
)
2431 mergeDocs("tdf113877_blank_bold_off.odt", "tdf113877_insert_numbered_list_abcd.odt");
2433 const OUString listId1
= getProperty
<OUString
>(getParagraph(1), "ListId");
2434 const OUString listId2
= getProperty
<OUString
>(getParagraph(2), "ListId");
2435 const OUString listId3
= getProperty
<OUString
>(getParagraph(3), "ListId");
2437 CPPUNIT_ASSERT_EQUAL(listId1
, listId2
);
2438 CPPUNIT_ASSERT_EQUAL(listId1
, listId3
);
2441 // just care that this does crash/assert
2442 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testRhbz1810732
) { mergeDocs(nullptr, "rhbz1810732.docx"); }
2444 CPPUNIT_TEST_FIXTURE(SwUiWriterTest4
, testTdf142157
)
2446 mergeDocs(nullptr, "tdf142157.odt");
2448 uno::Reference
<text::XTextSectionsSupplier
> xTextSectionsSupplier(mxComponent
, uno::UNO_QUERY
);
2449 uno::Reference
<container::XIndexAccess
> xSections(xTextSectionsSupplier
->getTextSections(),
2452 // Without the fix in place, this test would have failed with
2455 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections
->getCount());
2458 CPPUNIT_PLUGIN_IMPLEMENT();
2460 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */