1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <config_fonts.h>
12 #include <test/bootstrapfixture.hxx>
14 #include <cppunit/extensions/HelperMacros.h>
16 #include <editdoc.hxx>
18 #include <sfx2/app.hxx>
19 #include <svl/itempool.hxx>
20 #include <editeng/editeng.hxx>
21 #include <editeng/eeitem.hxx>
22 #include <editeng/lspcitem.hxx>
23 #include <editeng/svxacorr.hxx>
24 #include <editeng/unofield.hxx>
25 #include <editeng/wghtitem.hxx>
26 #include <editeng/postitem.hxx>
27 #include <editeng/section.hxx>
28 #include <editeng/editobj.hxx>
29 #include <editeng/flditem.hxx>
30 #include <editeng/udlnitem.hxx>
31 #include <svl/srchitem.hxx>
32 #include <svl/voiditem.hxx>
33 #include <editeng/fontitem.hxx>
34 #include <editeng/fhgtitem.hxx>
36 #include <com/sun/star/text/textfield/Type.hpp>
37 #include <com/sun/star/datatransfer/XTransferable.hpp>
40 #include <editeng/outliner.hxx>
42 using namespace com::sun::star
;
46 class Test
: public test::BootstrapFixture
53 test::BootstrapFixture::setUp();
54 mpItemPool
= new EditEngineItemPool();
55 SfxApplication::GetOrCreate();
58 void tearDown() override
61 test::BootstrapFixture::tearDown();
65 /// Test text portions position when percentage line spacing is set
66 void testLineSpacing();
69 void testConstruction();
71 /// Test UNO service class that implements text field items.
72 void testUnoTextFields();
75 void testAutocorrect();
77 /// Test Copy/Paste with hyperlinks in text using Legacy Format
78 void testHyperlinkCopyPaste();
80 /// Test Copy/Paste using Legacy Format
83 /// Test Paste using HTML
86 /// Test Paste using an HTML fragment
87 void testHTMLFragmentPaste();
89 /// Test Copy/Paste with selective selection over multiple paragraphs
90 void testMultiParaSelCopyPaste();
92 /// Test Copy/Paste with Tabs
93 void testTabsCopyPaste();
96 void testHyperlinkSearch();
98 /// Test Copy/Paste with Bold/Italic text using Legacy Format
99 void testBoldItalicCopyPaste();
101 /// Test Copy/Paste with Underline text using Legacy Format
102 void testUnderlineCopyPaste();
104 /// Test Copy/Paste with multiple paragraphs
105 void testMultiParaCopyPaste();
107 /// Test Copy/Paste with multiple paragraphs having Bold/Italic text
108 void testParaBoldItalicCopyPaste();
110 void testParaStartCopyPaste();
112 void testSectionAttributes();
114 void testLargeParaCopyPaste();
116 void testTransliterate();
118 void testTdf147196();
120 void testTdf148148();
122 void testSingleLine();
124 DECL_STATIC_LINK( Test
, CalcFieldValueHdl
, EditFieldInfo
*, void );
126 CPPUNIT_TEST_SUITE(Test
);
128 CPPUNIT_TEST(testLineSpacing
);
130 CPPUNIT_TEST(testConstruction
);
131 CPPUNIT_TEST(testUnoTextFields
);
132 CPPUNIT_TEST(testAutocorrect
);
133 CPPUNIT_TEST(testHyperlinkCopyPaste
);
134 CPPUNIT_TEST(testCopyPaste
);
135 CPPUNIT_TEST(testHTMLPaste
);
136 CPPUNIT_TEST(testHTMLFragmentPaste
);
137 CPPUNIT_TEST(testMultiParaSelCopyPaste
);
138 CPPUNIT_TEST(testTabsCopyPaste
);
139 CPPUNIT_TEST(testHyperlinkSearch
);
140 CPPUNIT_TEST(testBoldItalicCopyPaste
);
141 CPPUNIT_TEST(testUnderlineCopyPaste
);
142 CPPUNIT_TEST(testMultiParaCopyPaste
);
143 CPPUNIT_TEST(testParaBoldItalicCopyPaste
);
144 CPPUNIT_TEST(testParaStartCopyPaste
);
145 CPPUNIT_TEST(testSectionAttributes
);
146 CPPUNIT_TEST(testLargeParaCopyPaste
);
147 CPPUNIT_TEST(testTransliterate
);
148 CPPUNIT_TEST(testTdf147196
);
149 CPPUNIT_TEST(testTdf148148
);
150 CPPUNIT_TEST(testSingleLine
);
151 CPPUNIT_TEST_SUITE_END();
154 rtl::Reference
<EditEngineItemPool
> mpItemPool
;
158 void Test::testLineSpacing()
160 // Create EditEngine's instance
161 EditEngine
aEditEngine(mpItemPool
.get());
163 if(aEditEngine
.GetRefDevice()->GetDPIY() != 96
164 || aEditEngine
.GetRefDevice()->GetDPIScaleFactor() != 1.0)
167 // Get EditDoc for current EditEngine's instance
168 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
170 // Initially no text should be there
171 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rDoc
.GetTextLen());
172 CPPUNIT_ASSERT_EQUAL(OUString(), rDoc
.GetParaAsString(sal_Int32(0)));
175 OUString aText
= "This is multi-line paragraph";
177 sal_Int32 aTextLen
= aText
.getLength();
178 aEditEngine
.SetText(aText
);
180 // Assert changes - text insertion
181 CPPUNIT_ASSERT_EQUAL(aTextLen
, rDoc
.GetTextLen());
182 CPPUNIT_ASSERT_EQUAL(aText
, rDoc
.GetParaAsString(sal_Int32(0)));
184 // Select all paragraphs
185 ESelection
aSelection(0, 0, 0, aTextLen
);
187 auto doTest
= [&](sal_uInt16 nSpace
, sal_uInt16 nExpMaxAscent
, sal_uInt32 nExpLineHeight
)
189 std::unique_ptr
<SfxItemSet
> pSet(new SfxItemSet(aEditEngine
.GetEmptyItemSet()));
190 SvxLineSpacingItem
aLineSpacing(LINE_SPACE_DEFAULT_HEIGHT
, EE_PARA_SBL
);
191 aLineSpacing
.SetPropLineSpace(nSpace
);
192 pSet
->Put(aLineSpacing
);
195 SvxFontItem
aFont(EE_CHAR_FONTINFO
);
196 aFont
.SetFamilyName("Liberation Sans");
198 SvxFontHeightItem
aFontSize(240, 100, EE_CHAR_FONTHEIGHT
);
199 pSet
->Put(aFontSize
);
201 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(3), pSet
->Count());
203 aEditEngine
.QuickSetAttribs(*pSet
, aSelection
);
206 ParaPortion
* pParaPortion
= aEditEngine
.GetParaPortions()[0];
207 ContentNode
* const pNode
= pParaPortion
->GetNode();
208 const SvxLineSpacingItem
& rLSItem
= pNode
->GetContentAttribs().GetItem(EE_PARA_SBL
);
209 CPPUNIT_ASSERT_EQUAL(SvxInterLineSpaceRule::Prop
, rLSItem
.GetInterLineSpaceRule());
210 CPPUNIT_ASSERT_EQUAL(nSpace
, rLSItem
.GetPropLineSpace());
212 // Check the first line
213 ParagraphInfos aInfo
= aEditEngine
.GetParagraphInfos(0);
214 CPPUNIT_ASSERT_EQUAL(nExpMaxAscent
, aInfo
.nFirstLineMaxAscent
);
215 CPPUNIT_ASSERT_EQUAL(nExpLineHeight
, aEditEngine
.GetLineHeight(0));
218 // Test first case - 60%
219 doTest(60, 122, 153);
221 // Force multiple lines
222 aEditEngine
.SetPaperSize(Size(1000, 6000));
223 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aEditEngine
.GetLineCount(0));
225 // Test second case - 150%
226 doTest(150, 337, 382);
228 // Test lower Word limit - 6% (factor 0.06)
231 // Test upper Word limit - 13200% (factor 132)
232 doTest(13200, 33615, 33660);
236 void Test::testConstruction()
238 EditEngine
aEngine(mpItemPool
.get());
240 aEngine
.SetText("I am Edit Engine.");
243 bool includes(const uno::Sequence
<OUString
>& rSeq
, std::u16string_view rVal
)
245 for (OUString
const & s
: rSeq
)
252 void Test::testUnoTextFields()
256 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::DATE
));
257 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
258 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.DateTime");
259 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
264 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::URL
));
265 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
266 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.URL");
267 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
272 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::PAGE
));
273 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
274 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.PageNumber");
275 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
280 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::PAGES
));
281 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
282 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.PageCount");
283 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
288 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::TIME
));
289 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
290 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.DateTime");
291 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
296 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::DOCINFO_TITLE
));
297 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
298 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.docinfo.Title");
299 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
304 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::TABLE
));
305 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
306 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.SheetName");
307 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
312 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::EXTENDED_TIME
));
313 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
314 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.DateTime");
315 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
320 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::EXTENDED_FILE
));
321 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
322 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.FileName");
323 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
328 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::AUTHOR
));
329 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
330 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.Author");
331 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
336 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::MEASURE
));
337 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
338 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.Measure");
339 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
343 // PRESENTATION HEADER
344 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::PRESENTATION_HEADER
));
345 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
346 bool bGood
= includes(aSvcs
, u
"com.sun.star.presentation.textfield.Header");
347 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
351 // PRESENTATION FOOTER
352 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::PRESENTATION_FOOTER
));
353 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
354 bool bGood
= includes(aSvcs
, u
"com.sun.star.presentation.textfield.Footer");
355 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
359 // PRESENTATION DATE TIME
360 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::PRESENTATION_DATE_TIME
));
361 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
362 bool bGood
= includes(aSvcs
, u
"com.sun.star.presentation.textfield.DateTime");
363 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
367 class TestAutoCorrDoc
: public SvxAutoCorrDoc
370 /// just like the real thing, this dummy modifies the rText parameter :(
371 TestAutoCorrDoc(OUString
&rText
, LanguageType eLang
)
376 OUString
const& getResult() const
382 LanguageType m_eLang
;
383 virtual bool Delete( sal_Int32 nStt
, sal_Int32 nEnd
) override
385 //fprintf(stderr, "TestAutoCorrDoc::Delete\n");
386 m_rText
= m_rText
.replaceAt(nStt
, nEnd
-nStt
, u
"");
389 virtual bool Insert( sal_Int32 nPos
, const OUString
& rTxt
) override
391 //fprintf(stderr, "TestAutoCorrDoc::Insert\n");
392 m_rText
= m_rText
.replaceAt(nPos
, 0, rTxt
);
395 virtual bool Replace( sal_Int32 nPos
, const OUString
& rTxt
) override
397 //fprintf(stderr, "TestAutoCorrDoc::Replace\n");
398 return ReplaceRange( nPos
, rTxt
.getLength(), rTxt
);
400 virtual bool ReplaceRange( sal_Int32 nPos
, sal_Int32 nLen
, const OUString
& rTxt
) override
402 //fprintf(stderr, "TestAutoCorrDoc::ReplaceRange %d %d %s\n", nPos, nLen, OUStringToOString(rTxt, RTL_TEXTENCODING_UTF8).getStr());
403 m_rText
= m_rText
.replaceAt(nPos
, nLen
, rTxt
);
406 virtual void SetAttr( sal_Int32
, sal_Int32
, sal_uInt16
, SfxPoolItem
& ) override
408 //fprintf(stderr, "TestAutoCorrDoc::SetAttr\n");
410 virtual bool SetINetAttr( sal_Int32
, sal_Int32
, const OUString
& ) override
412 //fprintf(stderr, "TestAutoCorrDoc::SetINetAttr\n");
415 virtual OUString
const* GetPrevPara(bool) override
417 //fprintf(stderr, "TestAutoCorrDoc::GetPrevPara\n");
420 virtual bool ChgAutoCorrWord( sal_Int32
& rSttPos
,
421 sal_Int32 nEndPos
, SvxAutoCorrect
& rACorrect
,
422 OUString
* pPara
) override
424 //fprintf(stderr, "TestAutoCorrDoc::ChgAutoCorrWord\n");
426 if (m_rText
.isEmpty())
429 LanguageTag
aLanguageTag( m_eLang
);
430 const SvxAutocorrWord
* pFnd
= rACorrect
.SearchWordsInList(
431 m_rText
, rSttPos
, nEndPos
, *this, aLanguageTag
);
432 if (pFnd
&& pFnd
->IsTextOnly())
434 m_rText
= m_rText
.replaceAt(rSttPos
, nEndPos
, pFnd
->GetLong());
436 pPara
->clear(); // =&pCurNode->GetString();
442 virtual bool TransliterateRTLWord( sal_Int32
& /*rSttPos*/,
443 sal_Int32
/*nEndPos*/, bool /*bApply*/ ) override
449 //https://bugs.libreoffice.org/show_bug.cgi?id=55693
450 //Two capitalized letters are not corrected if dash or slash are directly
451 //before the two letters
452 void Test::testAutocorrect()
454 SvxAutoCorrect
aAutoCorrect((OUString()), (OUString()));
457 OUString
sInput("TEst-TEst");
458 sal_Unicode
const cNextChar(' ');
459 bool bNbspRunNext
= false;
461 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
462 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
464 CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", OUString("Test-Test "), aFoo
.getResult());
468 OUString
sInput("TEst/TEst");
469 sal_Unicode
const cNextChar(' ');
470 bool bNbspRunNext
= false;
472 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
473 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
475 CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", OUString("Test/Test "), aFoo
.getResult());
479 // test auto-bolding with '*'
480 OUString
sInput("*foo");
481 sal_Unicode
const cNextChar('*');
482 bool bNbspRunNext
= false;
484 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
485 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
487 CPPUNIT_ASSERT_EQUAL(OUString("foo"), aFoo
.getResult());
491 OUString
sInput("Test. test");
492 sal_Unicode
const cNextChar(' ');
493 bool bNbspRunNext
= false;
495 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
496 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
498 CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", OUString("Test. Test "), aFoo
.getResult());
501 // don't autocapitalize after a field mark
503 OUString
sInput("Test. \x01 test");
504 sal_Unicode
const cNextChar(' ');
505 bool bNbspRunNext
= false;
507 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
508 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
510 CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", OUString("Test. \x01 test "), aFoo
.getResult());
513 // consider field contents as text for auto quotes
515 OUString
sInput("T\x01");
516 sal_Unicode
const cNextChar('"');
517 static constexpr OUStringLiteral sExpected
= u
"T\x01\u201d";
518 bool bNbspRunNext
= false;
520 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
521 aAutoCorrect
.SetAutoCorrFlag(ACFlags::ChgQuotes
, true);
522 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
523 fprintf(stderr
, "text is %x\n", aFoo
.getResult()[aFoo
.getResult().getLength() - 1]);
525 CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", OUString(sExpected
), aFoo
.getResult());
530 IMPL_STATIC_LINK( Test
, CalcFieldValueHdl
, EditFieldInfo
*, pInfo
, void )
535 const SvxFieldItem
& rField
= pInfo
->GetField();
536 const SvxFieldData
* pField
= rField
.GetField();
537 if (const SvxURLField
* pURLField
= dynamic_cast<const SvxURLField
*>(pField
))
540 OUString aURL
= pURLField
->GetURL();
541 switch ( pURLField
->GetFormat() )
543 case SvxURLFormat::AppDefault
:
544 case SvxURLFormat::Repr
:
546 pInfo
->SetRepresentation( pURLField
->GetRepresentation() );
550 case SvxURLFormat::Url
:
552 pInfo
->SetRepresentation( aURL
);
559 OSL_FAIL("Unknown Field");
560 pInfo
->SetRepresentation(OUString('?'));
564 void Test::testHyperlinkCopyPaste()
566 // Create Outliner instance
567 Outliner
aOutliner(mpItemPool
.get(), OutlinerMode
569 aOutliner
.SetCalcFieldValueHdl( LINK( nullptr, Test
, CalcFieldValueHdl
) );
571 // Create EditEngine's instance
572 EditEngine
& aEditEngine
= const_cast<EditEngine
&> (aOutliner
.GetEditEngine());
574 // Get EditDoc for current EditEngine's instance
575 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
577 // New instance must be empty - no initial text
578 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
579 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
581 // Get corresponding Field Item for inserting URLs in text
583 OUString aURL1
= "mailto:///user@example.com";
584 OUString aRepres1
= "user@example.com";
585 SvxURLField
aURLField1( aURL1
, aRepres1
, SvxURLFormat::Repr
);
586 SvxFieldItem
aField1( aURLField1
, EE_FEATURE_FIELD
);
588 OUString aURL2
= "mailto:///example@domain.com";
589 OUString aRepres2
= "example@domain.com";
590 SvxURLField
aURLField2( aURL2
, aRepres2
, SvxURLFormat::Repr
);
591 SvxFieldItem
aField2( aURLField2
, EE_FEATURE_FIELD
);
593 // Insert initial text
594 OUString aParaText
= "sampletextfortestingfeaturefields";
595 // Positions Ref .............*13....*20..........
596 sal_Int32 aTextLen
= aParaText
.getLength();
597 aEditEngine
.SetText( aParaText
);
600 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
601 CPPUNIT_ASSERT_EQUAL( aParaText
, rDoc
.GetParaAsString(sal_Int32(0)) );
604 ContentNode
*pNode
= rDoc
.GetObject(0);
605 EditSelection
aSel1( EditPaM(pNode
, 13), EditPaM(pNode
, 13) );
606 aEditEngine
.InsertField( aSel1
, aField1
);
608 // Assert Field Count
609 CPPUNIT_ASSERT_EQUAL( sal_uInt16(1), aEditEngine
.GetFieldCount(0) );
612 EditSelection
aSel2( EditPaM(pNode
, 20 + 1), EditPaM(pNode
, 20 + 1) );
613 aEditEngine
.InsertField( aSel2
, aField2
);
615 // Assert Field Count
616 CPPUNIT_ASSERT_EQUAL( sal_uInt16(2), aEditEngine
.GetFieldCount(0) );
618 // Assert URL Fields and text before copy
620 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aRepres1
.getLength() + aRepres2
.getLength(), rDoc
.GetTextLen() );
621 CPPUNIT_ASSERT_EQUAL( OUString("sampletextforuser@example.comtestingexample@domain.comfeaturefields"), rDoc
.GetParaAsString(sal_Int32(0)) );
624 EFieldInfo aURLFieldInfo1
= aEditEngine
.GetFieldInfo( sal_Int32(0), sal_uInt16(0) );
625 CPPUNIT_ASSERT_EQUAL( sal_Int32(13), aURLFieldInfo1
.aPosition
.nIndex
);
626 CPPUNIT_ASSERT_EQUAL( sal_uInt16(EE_FEATURE_FIELD
), aURLFieldInfo1
.pFieldItem
->Which() );
627 SvxURLField
* pURLField1
= dynamic_cast<SvxURLField
*> ( const_cast<SvxFieldData
*> (aURLFieldInfo1
.pFieldItem
->GetField()) );
628 CPPUNIT_ASSERT(pURLField1
);
629 CPPUNIT_ASSERT_EQUAL( aURL1
, pURLField1
->GetURL() );
630 CPPUNIT_ASSERT_EQUAL( aRepres1
, pURLField1
->GetRepresentation() );
633 EFieldInfo aURLFieldInfo2
= aEditEngine
.GetFieldInfo( sal_Int32(0), sal_uInt16(1) );
634 CPPUNIT_ASSERT_EQUAL( sal_Int32(21), aURLFieldInfo2
.aPosition
.nIndex
);
635 CPPUNIT_ASSERT_EQUAL( sal_uInt16(EE_FEATURE_FIELD
), aURLFieldInfo2
.pFieldItem
->Which() );
636 SvxURLField
* pURLField2
= dynamic_cast<SvxURLField
*> ( const_cast<SvxFieldData
*> (aURLFieldInfo2
.pFieldItem
->GetField()) );
637 CPPUNIT_ASSERT(pURLField2
);
638 CPPUNIT_ASSERT_EQUAL( aURL2
, pURLField2
->GetURL() );
639 CPPUNIT_ASSERT_EQUAL( aRepres2
, pURLField2
->GetRepresentation() );
641 // Copy text using legacy format
642 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,10,0,21) );
644 // Paste text at the end
645 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
647 // Assert Changes ACP, ACP: after Copy/Paste
649 // Check the fields count
650 CPPUNIT_ASSERT_EQUAL( sal_uInt16(3), aEditEngine
.GetFieldCount(0) );
652 // Check the updated text length
653 CPPUNIT_ASSERT_EQUAL( aTextLen
+ 10 + aRepres1
.getLength()*2 + aRepres2
.getLength(), rDoc
.GetTextLen() );
655 // Check the updated text contents
656 CPPUNIT_ASSERT_EQUAL( OUString("sampletextforuser@example.comtestingexample@domain.comfeaturefieldsforuser@example.comtesting"), rDoc
.GetParaAsString(sal_Int32(0)) );
658 // Check the Fields and their values
661 EFieldInfo aACPURLFieldInfo1
= aEditEngine
.GetFieldInfo( sal_Int32(0), sal_uInt16(0) );
662 CPPUNIT_ASSERT_EQUAL( sal_Int32(13), aACPURLFieldInfo1
.aPosition
.nIndex
);
663 CPPUNIT_ASSERT_EQUAL( sal_uInt16(EE_FEATURE_FIELD
), aACPURLFieldInfo1
.pFieldItem
->Which() );
664 SvxURLField
* pACPURLField1
= dynamic_cast<SvxURLField
*> ( const_cast<SvxFieldData
*> (aACPURLFieldInfo1
.pFieldItem
->GetField()) );
665 CPPUNIT_ASSERT(pACPURLField1
);
666 CPPUNIT_ASSERT_EQUAL( aURL1
, pACPURLField1
->GetURL() );
667 CPPUNIT_ASSERT_EQUAL( aRepres1
, pACPURLField1
->GetRepresentation() );
670 EFieldInfo aACPURLFieldInfo2
= aEditEngine
.GetFieldInfo( sal_Int32(0), sal_uInt16(1) );
671 CPPUNIT_ASSERT_EQUAL( sal_Int32(21), aACPURLFieldInfo2
.aPosition
.nIndex
);
672 CPPUNIT_ASSERT_EQUAL( sal_uInt16(EE_FEATURE_FIELD
), aACPURLFieldInfo2
.pFieldItem
->Which() );
673 SvxURLField
* pACPURLField2
= dynamic_cast<SvxURLField
*> ( const_cast<SvxFieldData
*> (aACPURLFieldInfo2
.pFieldItem
->GetField()) );
674 CPPUNIT_ASSERT(pACPURLField2
);
675 CPPUNIT_ASSERT_EQUAL( aURL2
, pACPURLField2
->GetURL() );
676 CPPUNIT_ASSERT_EQUAL( aRepres2
, pACPURLField2
->GetRepresentation() ) ;
679 EFieldInfo aACPURLFieldInfo3
= aEditEngine
.GetFieldInfo( sal_Int32(0), sal_uInt16(2) );
680 CPPUNIT_ASSERT_EQUAL( sal_Int32(38), aACPURLFieldInfo3
.aPosition
.nIndex
);
681 CPPUNIT_ASSERT_EQUAL( sal_uInt16(EE_FEATURE_FIELD
), aACPURLFieldInfo3
.pFieldItem
->Which() );
682 SvxURLField
* pACPURLField3
= dynamic_cast<SvxURLField
*> ( const_cast<SvxFieldData
*> (aACPURLFieldInfo3
.pFieldItem
->GetField()) );
683 CPPUNIT_ASSERT(pACPURLField3
);
684 CPPUNIT_ASSERT_EQUAL( aURL1
, pACPURLField3
->GetURL() );
685 CPPUNIT_ASSERT_EQUAL( aRepres1
, pACPURLField3
->GetRepresentation() );
688 void Test::testCopyPaste()
690 // Create EditEngine's instance
691 EditEngine
aEditEngine( mpItemPool
.get() );
693 // Get EditDoc for current EditEngine's instance
694 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
696 // Initially no text should be there
697 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
698 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
701 OUString aText
= "This is custom initial text";
702 sal_Int32 aTextLen
= aText
.getLength();
703 aEditEngine
.SetText( aText
);
706 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
707 CPPUNIT_ASSERT_EQUAL( aText
, rDoc
.GetParaAsString(sal_Int32(0)) );
709 // Copy initial text using legacy format
710 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,0,0,aTextLen
) );
712 // Paste text at the end
713 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
716 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aTextLen
, rDoc
.GetTextLen() );
717 CPPUNIT_ASSERT_EQUAL( OUString(aText
+ aText
), rDoc
.GetParaAsString(sal_Int32(0)) );
720 /// XTransferable implementation that provides simple HTML content.
721 class TestHTMLTransferable
: public cppu::WeakImplHelper
<datatransfer::XTransferable
>
725 TestHTMLTransferable(const OString
& rHTML
);
726 uno::Any SAL_CALL
getTransferData(const datatransfer::DataFlavor
& rFlavor
) override
;
727 uno::Sequence
<datatransfer::DataFlavor
> SAL_CALL
getTransferDataFlavors() override
;
728 sal_Bool SAL_CALL
isDataFlavorSupported(const datatransfer::DataFlavor
& rFlavor
) override
;
731 TestHTMLTransferable::TestHTMLTransferable(const OString
& rHTML
)
736 uno::Any
TestHTMLTransferable::getTransferData(const datatransfer::DataFlavor
& rFlavor
)
738 if (rFlavor
.MimeType
!= "text/html")
744 SvMemoryStream aStream
;
745 aStream
.WriteOString(m_aHTML
);
746 aRet
<<= uno::Sequence
<sal_Int8
>(static_cast<const sal_Int8
*>(aStream
.GetData()), aStream
.GetSize());
750 uno::Sequence
<datatransfer::DataFlavor
> TestHTMLTransferable::getTransferDataFlavors()
752 datatransfer::DataFlavor aFlavor
;
753 aFlavor
.DataType
= cppu::UnoType
<uno::Sequence
<sal_Int8
>>::get();
754 aFlavor
.MimeType
= "text/html";
755 aFlavor
.HumanPresentableName
= aFlavor
.MimeType
;
759 sal_Bool
TestHTMLTransferable::isDataFlavorSupported(const datatransfer::DataFlavor
& rFlavor
)
761 return rFlavor
.MimeType
== "text/html"
762 && rFlavor
.DataType
== cppu::UnoType
<uno::Sequence
<sal_Int8
>>::get();
765 void Test::testHTMLPaste()
767 // Given an empty editeng document:
768 EditEngine
aEditEngine(mpItemPool
.get());
769 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
770 OString
aHTML("<!DOCTYPE html>\n<html><body>test</body></html>"_ostr
);
771 uno::Reference
< datatransfer::XTransferable
> xData(new TestHTMLTransferable(aHTML
));
773 // When trying to paste HTML:
774 aEditEngine
.InsertText(xData
, OUString(), rDoc
.GetEndPaM(), true);
776 // Then make sure the text gets pasted:
777 // Without the accompanying fix in place, this test would have failed with:
780 // i.e. RTF and plain text paste worked, but not HTML.
781 CPPUNIT_ASSERT_EQUAL(OUString("test"), rDoc
.GetParaAsString(static_cast<sal_Int32
>(0)));
784 void Test::testHTMLFragmentPaste()
786 // Given an empty editeng document:
787 EditEngine
aEditEngine(mpItemPool
.get());
788 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
789 OString
aHTML("a<b>b</b>c"_ostr
);
790 uno::Reference
< datatransfer::XTransferable
> xData(new TestHTMLTransferable(aHTML
));
792 // When trying to paste an HTML fragment:
793 aEditEngine
.InsertText(xData
, OUString(), rDoc
.GetEndPaM(), true);
795 // Then make sure the text gets pasted:
796 // Without the accompanying fix in place, this test would have failed with:
799 // i.e. a HTML fragment without a proper header was ignored on paste.
800 CPPUNIT_ASSERT_EQUAL(OUString("abc"), rDoc
.GetParaAsString(static_cast<sal_Int32
>(0)));
803 void Test::testMultiParaSelCopyPaste()
805 // Create EditEngine's instance
806 EditEngine
aEditEngine( mpItemPool
.get() );
808 // Get EditDoc for current EditEngine's instance
809 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
811 // Initially no text should be there
812 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
813 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
815 // Insert initial text
816 OUString aFirstPara
= "This is first paragraph";
817 // Selection Ref ........8..............
818 OUString aSecondPara
= "This is second paragraph";
819 // Selection Ref .............14.........
820 OUString aThirdPara
= "This is third paragraph";
821 OUString aText
= aFirstPara
+ "\n" + aSecondPara
+ "\n" + aThirdPara
;
822 sal_Int32 aTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength() + aThirdPara
.getLength();
823 aEditEngine
.SetText( aText
);
824 OUString aCopyText
= "first paragraphThis is second";
825 sal_Int32 aCopyTextLen
= aCopyText
.getLength();
828 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
829 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
830 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
831 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
833 // Copy initial text using legacy format
834 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,8,1,14) );
836 // Paste text at the end
837 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
840 OUString aThirdParaAfterCopyPaste
= aThirdPara
+ "first paragraph";
841 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aCopyTextLen
, rDoc
.GetTextLen() );
842 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
843 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
844 CPPUNIT_ASSERT_EQUAL( aThirdParaAfterCopyPaste
, rDoc
.GetParaAsString(sal_Int32(2)) );
845 CPPUNIT_ASSERT_EQUAL( OUString("This is second"), rDoc
.GetParaAsString(sal_Int32(3)) );
848 void Test::testTabsCopyPaste()
850 // Create EditEngine's instance
851 EditEngine
aEditEngine( mpItemPool
.get() );
853 // Get EditDoc for current EditEngine's instance
854 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
856 // New instance must be empty - no initial text
857 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
858 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
860 // Get corresponding Item for inserting tabs in the text
861 SfxVoidItem
aTab( EE_FEATURE_TAB
);
863 // Insert initial text
864 OUString aParaText
= "sampletextfortestingtab";
865 // Positions Ref ......*6...............*23
866 sal_Int32 aTextLen
= aParaText
.getLength();
867 aEditEngine
.SetText( aParaText
);
870 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
871 CPPUNIT_ASSERT_EQUAL( aParaText
, rDoc
.GetParaAsString(sal_Int32(0)) );
873 // Insert tab 1 at desired position
874 ContentNode
*pNode
= rDoc
.GetObject(0);
875 EditSelection
aSel1( EditPaM(pNode
, 6), EditPaM(pNode
, 6) );
876 aEditEngine
.InsertFeature( aSel1
, aTab
);
879 CPPUNIT_ASSERT_EQUAL( aTextLen
+ 1, rDoc
.GetTextLen() );
880 CPPUNIT_ASSERT_EQUAL( OUString("sample\ttextfortestingtab"), rDoc
.GetParaAsString(sal_Int32(0)) );
882 // Insert tab 2 at desired position
883 EditSelection
aSel2( EditPaM(pNode
, 23+1), EditPaM(pNode
, 23+1) );
884 aEditEngine
.InsertFeature( aSel2
, aTab
);
887 CPPUNIT_ASSERT_EQUAL( aTextLen
+ 2, rDoc
.GetTextLen() );
888 CPPUNIT_ASSERT_EQUAL( OUString("sample\ttextfortestingtab\t"), rDoc
.GetParaAsString(sal_Int32(0)) );
890 // Copy text using legacy format
891 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,6,0,aTextLen
+2) );
893 // Paste text at the end
894 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
897 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aTextLen
- 6 + 4, rDoc
.GetTextLen() );
898 CPPUNIT_ASSERT_EQUAL( OUString("sample\ttextfortestingtab\t\ttextfortestingtab\t"), rDoc
.GetParaAsString(sal_Int32(0)) );
901 class UrlEditEngine
: public EditEngine
904 explicit UrlEditEngine(SfxItemPool
*pPool
) : EditEngine(pPool
) {}
906 virtual OUString
CalcFieldValue( const SvxFieldItem
&, sal_Int32
, sal_Int32
, std::optional
<Color
>&, std::optional
<Color
>&, std::optional
<FontLineStyle
>& ) override
908 return "jim@bob.com"; // a sophisticated view of value:
912 // Odd accounting for hyperlink position & size etc.
913 // https://bugzilla.novell.com/show_bug.cgi?id=467459
914 void Test::testHyperlinkSearch()
916 UrlEditEngine
aEngine(mpItemPool
.get());
917 EditDoc
&rDoc
= aEngine
.GetEditDoc();
919 OUString aSampleText
= "Please write email to . if you find a fish(not a dog).";
920 aEngine
.SetText(aSampleText
);
922 CPPUNIT_ASSERT_EQUAL_MESSAGE("set text", aSampleText
, rDoc
.GetParaAsString(sal_Int32(0)));
924 ContentNode
*pNode
= rDoc
.GetObject(0);
925 EditSelection
aSel(EditPaM(pNode
, 22), EditPaM(pNode
, 22));
926 SvxURLField
aURLField("mailto:///jim@bob.com", "jim@bob.com",
928 SvxFieldItem
aField(aURLField
, EE_FEATURE_FIELD
);
930 aEngine
.InsertField(aSel
, aField
);
932 OUString aContent
= pNode
->GetExpandedText();
933 CPPUNIT_ASSERT_EQUAL_MESSAGE("get text", OUString("Please write email to jim@bob.com. if you find a fish(not a dog)."),
935 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong length", aContent
.getLength(), rDoc
.GetTextLen());
937 // Check expansion and positioning re-work
938 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong length", aContent
.getLength(),
939 pNode
->GetExpandedLen());
940 for (sal_Int32 n
= 0; n
< aContent
.getLength(); n
++)
942 sal_Int32 nStart
= n
, nEnd
= n
;
943 pNode
->UnExpandPositions(nStart
,nEnd
);
944 CPPUNIT_ASSERT_MESSAGE("out of bound start", nStart
< pNode
->Len());
945 CPPUNIT_ASSERT_MESSAGE("out of bound end", nEnd
<= pNode
->Len());
948 static const struct {
949 sal_Int32 mnStart
, mnEnd
;
950 sal_Int32 mnNewStart
, mnNewEnd
;
952 { 0, 1, /* -> */ 0, 1 },
953 { 21, 25, /* -> */ 21, 23 }, // the field is really just one char
954 { 25, 27, /* -> */ 22, 23 },
955 { 50, 56, /* -> */ 40, 46 }
957 for (size_t n
= 0; n
< SAL_N_ELEMENTS(aTrickyOnes
); n
++)
959 sal_Int32 nStart
= aTrickyOnes
[n
].mnStart
;
960 sal_Int32 nEnd
= aTrickyOnes
[n
].mnEnd
;
961 pNode
->UnExpandPositions(nStart
,nEnd
);
963 CPPUNIT_ASSERT_EQUAL_MESSAGE(
964 OString("in row " + OString::number(n
)).getStr(),
965 aTrickyOnes
[n
].mnNewStart
, nStart
);
966 CPPUNIT_ASSERT_EQUAL_MESSAGE(
967 OString("in row " + OString::number(n
)).getStr(),
968 aTrickyOnes
[n
].mnNewEnd
, nEnd
);
971 SvxSearchItem
aItem(1); //SID_SEARCH_ITEM);
972 aItem
.SetBackward(false);
973 aItem
.SetSelection(false);
974 aItem
.SetSearchString("fish");
975 CPPUNIT_ASSERT_MESSAGE("no fish", aEngine
.HasText(aItem
));
976 aItem
.SetSearchString("dog");
977 CPPUNIT_ASSERT_MESSAGE("no dog", aEngine
.HasText(aItem
));
980 bool hasBold(const editeng::Section
& rSecAttr
)
982 return std::any_of(rSecAttr
.maAttributes
.begin(), rSecAttr
.maAttributes
.end(),
983 [](const SfxPoolItem
* p
) {
984 return p
->Which() == EE_CHAR_WEIGHT
985 && static_cast<const SvxWeightItem
*>(p
)->GetWeight() == WEIGHT_BOLD
;
989 bool hasItalic(const editeng::Section
& rSecAttr
)
991 return std::any_of(rSecAttr
.maAttributes
.begin(), rSecAttr
.maAttributes
.end(),
992 [](const SfxPoolItem
* p
) {
993 return p
->Which() == EE_CHAR_ITALIC
994 && static_cast<const SvxPostureItem
*>(p
)->GetPosture() == ITALIC_NORMAL
;
998 void Test::testBoldItalicCopyPaste()
1000 // Create EditEngine's instance
1001 EditEngine
aEditEngine( mpItemPool
.get() );
1003 // Get EditDoc for current EditEngine's instance
1004 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
1006 // New instance must be empty - no initial text
1007 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
1008 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
1010 // Get corresponding ItemSet for inserting Bold/Italic text
1011 std::unique_ptr
<SfxItemSet
> pSet( new SfxItemSet(aEditEngine
.GetEmptyItemSet()) );
1012 SvxWeightItem
aBold( WEIGHT_BOLD
, EE_CHAR_WEIGHT
);
1013 SvxPostureItem
aItalic( ITALIC_NORMAL
, EE_CHAR_ITALIC
);
1015 // Insert initial text
1016 OUString aParaText
= "boldeditengineitalic";
1017 // Positions Ref ..*2....*8...*13.*17
1018 // Bold Ref ..[ BOLD ]......
1019 // Italic Ref ........[ ITALIC ]..
1020 sal_Int32 aTextLen
= aParaText
.getLength();
1021 aEditEngine
.SetText( aParaText
);
1023 // Assert changes - text insertion
1024 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
1025 CPPUNIT_ASSERT_EQUAL( aParaText
, rDoc
.GetParaAsString(sal_Int32(0)) );
1027 // Apply Bold to appropriate selection
1029 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16
>(1), pSet
->Count() );
1030 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(0,2,0,14) );
1033 std::unique_ptr
<EditTextObject
> pEditText1( aEditEngine
.CreateTextObject() );
1034 std::vector
<editeng::Section
> aAttrs1
;
1035 pEditText1
->GetAllSections( aAttrs1
);
1036 // There should be 3 sections - woBold - wBold - woBold (w - with, wo - without)
1037 CPPUNIT_ASSERT_EQUAL( size_t(3), aAttrs1
.size() );
1039 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnParagraph
) );
1040 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnStart
) );
1041 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs1
[0].mnEnd
) );
1042 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].maAttributes
.size()) );
1044 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[1].mnParagraph
) );
1045 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs1
[1].mnStart
) );
1046 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs1
[1].mnEnd
) );
1047 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[1].maAttributes
.size()) );
1048 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs1
[1]) );
1050 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].mnParagraph
) );
1051 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs1
[2].mnStart
) );
1052 CPPUNIT_ASSERT_EQUAL( 20, static_cast<int>(aAttrs1
[2].mnEnd
) );
1053 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].maAttributes
.size()) );
1055 // Apply Italic to appropriate selection
1056 pSet
.reset( new SfxItemSet(aEditEngine
.GetEmptyItemSet()) );
1058 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16
>(1), pSet
->Count() );
1059 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(0,8,0,18) );
1062 std::unique_ptr
<EditTextObject
> pEditText2( aEditEngine
.CreateTextObject() );
1063 std::vector
<editeng::Section
> aAttrs2
;
1064 pEditText2
->GetAllSections( aAttrs2
);
1065 // There should be 5 sections - woBold&woItalic - wBold&woItalic - wBold&wItalic - woBold&wItalic - woBold&woItalic (w - with, wo - without)
1066 CPPUNIT_ASSERT_EQUAL( size_t(5), aAttrs2
.size() );
1068 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnParagraph
) );
1069 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnStart
) );
1070 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[0].mnEnd
) );
1071 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].maAttributes
.size()) );
1073 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[1].mnParagraph
) );
1074 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[1].mnStart
) );
1075 CPPUNIT_ASSERT_EQUAL( 8, static_cast<int>(aAttrs2
[1].mnEnd
) );
1076 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[1].maAttributes
.size()) );
1077 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs2
[1]) );
1079 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[2].mnParagraph
) );
1080 CPPUNIT_ASSERT_EQUAL( 8, static_cast<int>(aAttrs2
[2].mnStart
) );
1081 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs2
[2].mnEnd
) );
1082 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[2].maAttributes
.size()) );
1083 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs2
[2]) );
1084 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs2
[2]) );
1086 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[3].mnParagraph
) );
1087 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs2
[3].mnStart
) );
1088 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[3].mnEnd
) );
1089 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[3].maAttributes
.size()) );
1090 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs2
[3]) );
1092 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[4].mnParagraph
) );
1093 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[4].mnStart
) );
1094 CPPUNIT_ASSERT_EQUAL( 20, static_cast<int>(aAttrs2
[4].mnEnd
) );
1095 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[4].maAttributes
.size()) );
1097 // Copy text using legacy format
1098 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,1,0,aTextLen
-1) );
1100 // Paste text at the end
1101 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
1104 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aTextLen
- 2, rDoc
.GetTextLen() );
1105 CPPUNIT_ASSERT_EQUAL( OUString(aParaText
+ "oldeditengineitali" ), rDoc
.GetParaAsString(sal_Int32(0)) );
1107 // Check updated text for appropriate Bold/Italics
1108 std::unique_ptr
<EditTextObject
> pEditText3( aEditEngine
.CreateTextObject() );
1109 std::vector
<editeng::Section
> aAttrs3
;
1110 pEditText3
->GetAllSections( aAttrs3
);
1111 // There should be 9 sections - woBold&woItalic - wBold&woItalic - wBold&wItalic - woBold&wItalic - woBold&woItalic - wBold&woItalic
1112 // - wBold&wItalic - woBold&wItalic - woBold&woItalic(w - with, wo - without)
1113 CPPUNIT_ASSERT_EQUAL( size_t(9), aAttrs3
.size() );
1115 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].mnParagraph
) );
1116 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].mnStart
) );
1117 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[0].mnEnd
) );
1118 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].maAttributes
.size()) );
1120 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[1].mnParagraph
) );
1121 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[1].mnStart
) );
1122 CPPUNIT_ASSERT_EQUAL( 8, static_cast<int>(aAttrs3
[1].mnEnd
) );
1123 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[1].maAttributes
.size()) );
1124 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[1]) );
1126 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[2].mnParagraph
) );
1127 CPPUNIT_ASSERT_EQUAL( 8, static_cast<int>(aAttrs3
[2].mnStart
) );
1128 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs3
[2].mnEnd
) );
1129 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[2].maAttributes
.size()) );
1130 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[2]) );
1131 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[2]) );
1133 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[3].mnParagraph
) );
1134 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs3
[3].mnStart
) );
1135 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs3
[3].mnEnd
) );
1136 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[3].maAttributes
.size()) );
1137 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[3]) );
1139 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[4].mnParagraph
) );
1140 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs3
[4].mnStart
) );
1141 CPPUNIT_ASSERT_EQUAL( 21, static_cast<int>(aAttrs3
[4].mnEnd
) );
1142 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[4].maAttributes
.size()) );
1144 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[5].mnParagraph
) );
1145 CPPUNIT_ASSERT_EQUAL( 21, static_cast<int>(aAttrs3
[5].mnStart
) );
1146 CPPUNIT_ASSERT_EQUAL( 27, static_cast<int>(aAttrs3
[5].mnEnd
) );
1147 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[5].maAttributes
.size()) );
1148 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[5]) );
1150 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[6].mnParagraph
) );
1151 CPPUNIT_ASSERT_EQUAL( 27, static_cast<int>(aAttrs3
[6].mnStart
) );
1152 CPPUNIT_ASSERT_EQUAL( 33, static_cast<int>(aAttrs3
[6].mnEnd
) );
1153 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[6].maAttributes
.size()) );
1154 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[6]) );
1155 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[6]) );
1157 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[7].mnParagraph
) );
1158 CPPUNIT_ASSERT_EQUAL( 33, static_cast<int>(aAttrs3
[7].mnStart
) );
1159 CPPUNIT_ASSERT_EQUAL( 37, static_cast<int>(aAttrs3
[7].mnEnd
) );
1160 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[7].maAttributes
.size()) );
1161 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[7]) );
1163 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[8].mnParagraph
) );
1164 CPPUNIT_ASSERT_EQUAL( 37, static_cast<int>(aAttrs3
[8].mnStart
) );
1165 CPPUNIT_ASSERT_EQUAL( 38, static_cast<int>(aAttrs3
[8].mnEnd
) );
1166 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[8].maAttributes
.size()) );
1169 // Auxiliary function to test Underline text Copy/Paste using Legacy Format
1170 bool hasUnderline(const editeng::Section
& rSecAttr
)
1172 return std::any_of(rSecAttr
.maAttributes
.begin(), rSecAttr
.maAttributes
.end(),
1173 [](const SfxPoolItem
* p
) {
1174 return p
->Which() == EE_CHAR_UNDERLINE
1175 && static_cast<const SvxUnderlineItem
*>(p
)->GetLineStyle() == LINESTYLE_SINGLE
;
1179 void Test::testUnderlineCopyPaste()
1181 // Create EditEngine's instance
1182 EditEngine
aEditEngine( mpItemPool
.get() );
1184 // Get EditDoc for current EditEngine's instance
1185 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
1187 // New instance must be empty - no initial text
1188 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
1189 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
1191 // Get corresponding ItemSet for inserting Underline text
1192 std::unique_ptr
<SfxItemSet
> pSet( new SfxItemSet(aEditEngine
.GetEmptyItemSet()) );
1193 SvxUnderlineItem
aULine( LINESTYLE_SINGLE
, EE_CHAR_UNDERLINE
);
1195 // Insert initial text
1196 OUString aParaText
= "sampletextforunderline";
1197 // Positions Ref ......*6.........*17..
1198 // Underline Ref ......[UNDERLINE ]....
1199 sal_Int32 aTextLen
= aParaText
.getLength();
1200 aEditEngine
.SetText( aParaText
);
1202 // Apply Underline style
1203 pSet
->Put( aULine
);
1204 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16
>(1), pSet
->Count() );
1205 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(0,6,0,18) );
1208 std::unique_ptr
<EditTextObject
> pEditText1( aEditEngine
.CreateTextObject() );
1209 std::vector
<editeng::Section
> aAttrs1
;
1210 pEditText1
->GetAllSections( aAttrs1
);
1212 // There should be 3 sections - woUnderline - wUnderline - woUnderline (w - with, wo - without)
1213 CPPUNIT_ASSERT_EQUAL( size_t(3), aAttrs1
.size() );
1215 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnParagraph
) );
1216 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnStart
) );
1217 CPPUNIT_ASSERT_EQUAL( 6, static_cast<int>(aAttrs1
[0].mnEnd
) );
1218 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].maAttributes
.size()) );
1220 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[1].mnParagraph
) );
1221 CPPUNIT_ASSERT_EQUAL( 6, static_cast<int>(aAttrs1
[1].mnStart
) );
1222 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs1
[1].mnEnd
) );
1223 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[1].maAttributes
.size()) );
1224 CPPUNIT_ASSERT_MESSAGE( "This section must be underlined.", hasUnderline(aAttrs1
[1]) );
1226 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].mnParagraph
) );
1227 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs1
[2].mnStart
) );
1228 CPPUNIT_ASSERT_EQUAL( 22, static_cast<int>(aAttrs1
[2].mnEnd
) );
1229 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].maAttributes
.size()) );
1231 // Copy text using legacy format
1232 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,6,0,aTextLen
-4) );
1234 // Paste text at the end
1235 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
1238 CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32
>(aTextLen
+ strlen("textforunder")), rDoc
.GetTextLen() );
1239 CPPUNIT_ASSERT_EQUAL( OUString(aParaText
+ "textforunder" ), rDoc
.GetParaAsString(sal_Int32(0)) );
1241 // Check updated text for appropriate Underline
1242 std::unique_ptr
<EditTextObject
> pEditText2( aEditEngine
.CreateTextObject() );
1243 std::vector
<editeng::Section
> aAttrs2
;
1244 pEditText2
->GetAllSections( aAttrs2
);
1246 // There should be 4 sections - woUnderline - wUnderline - woUnderline - wUnderline (w - with, wo - without)
1247 CPPUNIT_ASSERT_EQUAL( size_t(4), aAttrs2
.size() );
1249 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnParagraph
) );
1250 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnStart
) );
1251 CPPUNIT_ASSERT_EQUAL( 6, static_cast<int>(aAttrs2
[0].mnEnd
) );
1252 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].maAttributes
.size()) );
1254 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[1].mnParagraph
) );
1255 CPPUNIT_ASSERT_EQUAL( 6, static_cast<int>(aAttrs2
[1].mnStart
) );
1256 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[1].mnEnd
) );
1257 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[1].maAttributes
.size()) );
1258 CPPUNIT_ASSERT_MESSAGE( "This section must be underlined.", hasUnderline(aAttrs2
[1]) );
1260 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[2].mnParagraph
) );
1261 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[2].mnStart
) );
1262 CPPUNIT_ASSERT_EQUAL( 22, static_cast<int>(aAttrs2
[2].mnEnd
) );
1263 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[2].maAttributes
.size()) );
1265 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[3].mnParagraph
) );
1266 CPPUNIT_ASSERT_EQUAL( 22, static_cast<int>(aAttrs2
[3].mnStart
) );
1267 CPPUNIT_ASSERT_EQUAL( 34, static_cast<int>(aAttrs2
[3].mnEnd
) );
1268 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[3].maAttributes
.size()) );
1269 CPPUNIT_ASSERT_MESSAGE( "This section must be underlined.", hasUnderline(aAttrs2
[3]) );
1272 void Test::testMultiParaCopyPaste()
1274 // Create EditEngine's instance
1275 EditEngine
aEditEngine( mpItemPool
.get() );
1277 // Get EditDoc for current EditEngine's instance
1278 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
1280 // Initially no text should be there
1281 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
1282 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
1284 // Insert initial text
1285 OUString aFirstPara
= "This is first paragraph";
1286 OUString aSecondPara
= "This is second paragraph";
1287 OUString aThirdPara
= "This is third paragraph";
1288 OUString aText
= aFirstPara
+ "\n" + aSecondPara
+ "\n" + aThirdPara
;
1289 sal_Int32 aTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength() + aThirdPara
.getLength();
1290 aEditEngine
.SetText( aText
);
1291 sal_Int32 aCopyTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength();
1294 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
1295 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1296 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1297 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1299 // Copy initial text using legacy format
1300 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,0,1,aSecondPara
.getLength()) );
1302 // Paste text at the end
1303 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
1306 OUString aThirdParaAfterCopyPaste
= aThirdPara
+ aFirstPara
;
1307 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aCopyTextLen
, rDoc
.GetTextLen() );
1308 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1309 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1310 CPPUNIT_ASSERT_EQUAL( aThirdParaAfterCopyPaste
, rDoc
.GetParaAsString(sal_Int32(2)) );
1311 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(3)) );
1314 void Test::testParaBoldItalicCopyPaste()
1316 // Create EditEngine's instance
1317 EditEngine
aEditEngine( mpItemPool
.get() );
1319 // Get EditDoc for current EditEngine's instance
1320 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
1322 // Initially no text should be there
1323 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
1324 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
1326 // Get corresponding ItemSet for inserting Bold/Italic text
1327 std::unique_ptr
<SfxItemSet
> pSet( new SfxItemSet(aEditEngine
.GetEmptyItemSet()) );
1328 SvxWeightItem
aBold( WEIGHT_BOLD
, EE_CHAR_WEIGHT
);
1329 SvxPostureItem
aItalic( ITALIC_NORMAL
, EE_CHAR_ITALIC
);
1331 // Insert initial text
1332 OUString aFirstPara
= "This is first paragraph";
1333 // Positions Ref .....*5.*8....*14*17...
1334 // Bold Ref .....[ BOLD ].....
1335 // Italic Ref ..............[ ITA
1336 // Copy Ref ........[ Copy Sel
1337 OUString aSecondPara
= "This is second paragraph";
1338 // Positions Ref .....*5.*8...*13..*18...
1339 // Bold Ref .....[ BOLD ].....
1340 // Italic Ref LIC ]...............
1341 // Copy Ref ection ]..........
1342 OUString aThirdPara
= "This is third paragraph";
1343 OUString aText
= aFirstPara
+ "\n" + aSecondPara
+ "\n" + aThirdPara
;
1344 sal_Int32 aTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength() + aThirdPara
.getLength();
1345 aEditEngine
.SetText( aText
);
1346 OUString aCopyText
= "first paragraphThis is second";
1347 sal_Int32 aCopyTextLen
= aCopyText
.getLength();
1349 // Assert changes - text insertion
1350 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
1351 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1352 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1353 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1355 // Apply Bold to appropriate selections
1357 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16
>(1), pSet
->Count() );
1358 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(0,5,0,18) );
1359 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(1,5,1,19) );
1362 std::unique_ptr
<EditTextObject
> pEditText1( aEditEngine
.CreateTextObject() );
1363 std::vector
<editeng::Section
> aAttrs1
;
1364 pEditText1
->GetAllSections( aAttrs1
);
1365 // There should be 7 sections - woB - wB - woB -woB -wB -woB -woB (w - with, wo - without, B - Bold, I - Italic)
1366 CPPUNIT_ASSERT_EQUAL( size_t(7), aAttrs1
.size() );
1368 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnParagraph
) );
1369 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnStart
) );
1370 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs1
[0].mnEnd
) );
1371 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].maAttributes
.size()) );
1373 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[1].mnParagraph
) );
1374 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs1
[1].mnStart
) );
1375 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs1
[1].mnEnd
) );
1376 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[1].maAttributes
.size()) );
1377 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs1
[1]) );
1379 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].mnParagraph
) );
1380 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs1
[2].mnStart
) );
1381 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs1
[2].mnEnd
) );
1382 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].maAttributes
.size()) );
1384 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[3].mnParagraph
) );
1385 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[3].mnStart
) );
1386 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs1
[3].mnEnd
) );
1387 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[3].maAttributes
.size()) );
1389 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[4].mnParagraph
) );
1390 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs1
[4].mnStart
) );
1391 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs1
[4].mnEnd
) );
1392 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[4].maAttributes
.size()) );
1393 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs1
[4]) );
1395 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[5].mnParagraph
) );
1396 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs1
[5].mnStart
) );
1397 CPPUNIT_ASSERT_EQUAL( 24, static_cast<int>(aAttrs1
[5].mnEnd
) );
1398 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[5].maAttributes
.size()) );
1400 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs1
[6].mnParagraph
) );
1401 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[6].mnStart
) );
1402 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs1
[6].mnEnd
) );
1403 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[6].maAttributes
.size()) );
1405 // Apply Italic to appropriate selection
1406 pSet
.reset( new SfxItemSet(aEditEngine
.GetEmptyItemSet()) );
1408 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16
>(1), pSet
->Count() );
1409 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(0,14,1,9) );
1412 std::unique_ptr
<EditTextObject
> pEditText2( aEditEngine
.CreateTextObject() );
1413 std::vector
<editeng::Section
> aAttrs2
;
1414 pEditText2
->GetAllSections( aAttrs2
);
1415 // There should be 9 sections - woB&woI - wB&woI - wB&wI -woB&wI - woB&wI - wB&wI - wB&woI - woB&woI - woB&woI (w - with, wo - without, B - Bold, I - Italic)
1416 CPPUNIT_ASSERT_EQUAL( size_t(9), aAttrs2
.size() );
1418 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnParagraph
) );
1419 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnStart
) );
1420 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs2
[0].mnEnd
) );
1421 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].maAttributes
.size()) );
1423 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[1].mnParagraph
) );
1424 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs2
[1].mnStart
) );
1425 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs2
[1].mnEnd
) );
1426 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[1].maAttributes
.size()) );
1427 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs2
[1]) );
1429 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[2].mnParagraph
) );
1430 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs2
[2].mnStart
) );
1431 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[2].mnEnd
) );
1432 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[2].maAttributes
.size()) );
1433 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs2
[2]) );
1434 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs2
[2]) );
1436 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[3].mnParagraph
) );
1437 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[3].mnStart
) );
1438 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs2
[3].mnEnd
) );
1439 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[3].maAttributes
.size()) );
1440 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs2
[3]) );
1442 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[4].mnParagraph
) );
1443 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[4].mnStart
) );
1444 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs2
[4].mnEnd
) );
1445 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[4].maAttributes
.size()) );
1446 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs2
[4]) );
1448 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[5].mnParagraph
) );
1449 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs2
[5].mnStart
) );
1450 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs2
[5].mnEnd
) );
1451 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[5].maAttributes
.size()) );
1452 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs2
[5]) );
1453 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs2
[5]) );
1455 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[6].mnParagraph
) );
1456 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs2
[6].mnStart
) );
1457 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs2
[6].mnEnd
) );
1458 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[6].maAttributes
.size()) );
1459 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs2
[6]) );
1461 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[7].mnParagraph
) );
1462 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs2
[7].mnStart
) );
1463 CPPUNIT_ASSERT_EQUAL( 24, static_cast<int>(aAttrs2
[7].mnEnd
) );
1464 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[7].maAttributes
.size()) );
1466 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[8].mnParagraph
) );
1467 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[8].mnStart
) );
1468 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs2
[8].mnEnd
) );
1469 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[8].maAttributes
.size()) );
1471 // Copy text using legacy format
1472 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,8,1,14) );
1474 // Paste text at the end
1475 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
1478 OUString aThirdParaAfterCopyPaste
= aThirdPara
+ "first paragraph";
1479 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aCopyTextLen
, rDoc
.GetTextLen() );
1480 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1481 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1482 CPPUNIT_ASSERT_EQUAL( aThirdParaAfterCopyPaste
, rDoc
.GetParaAsString(sal_Int32(2)) );
1483 CPPUNIT_ASSERT_EQUAL( OUString("This is second"), rDoc
.GetParaAsString(sal_Int32(3)) );
1485 // Check updated text for appropriate Bold/Italics
1486 std::unique_ptr
<EditTextObject
> pEditText3( aEditEngine
.CreateTextObject() );
1487 std::vector
<editeng::Section
> aAttrs3
;
1488 pEditText3
->GetAllSections( aAttrs3
);
1489 // There should be 15 sections - woB&woI - wB&woI - wB&wI -woB&wI - woB&wI - wB&wI - wB&woI - woB&woI - woB&woI
1490 // - wB&woI - wB&wI - woB&wI - -woB&wI - wB&wI - wB&woI (w - with, wo - without, B - Bold, I - Italic)
1491 CPPUNIT_ASSERT_EQUAL( size_t(15), aAttrs3
.size() );
1493 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].mnParagraph
) );
1494 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].mnStart
) );
1495 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[0].mnEnd
) );
1496 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].maAttributes
.size()) );
1498 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[1].mnParagraph
) );
1499 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[1].mnStart
) );
1500 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs3
[1].mnEnd
) );
1501 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[1].maAttributes
.size()) );
1502 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[1]) );
1504 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[2].mnParagraph
) );
1505 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs3
[2].mnStart
) );
1506 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs3
[2].mnEnd
) );
1507 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[2].maAttributes
.size()) );
1508 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[2]) );
1509 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[2]) );
1511 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[3].mnParagraph
) );
1512 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs3
[3].mnStart
) );
1513 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs3
[3].mnEnd
) );
1514 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[3].maAttributes
.size()) );
1515 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[3]) );
1517 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[4].mnParagraph
) );
1518 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[4].mnStart
) );
1519 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[4].mnEnd
) );
1520 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[4].maAttributes
.size()) );
1521 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[4]) );
1523 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[5].mnParagraph
) );
1524 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[5].mnStart
) );
1525 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs3
[5].mnEnd
) );
1526 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[5].maAttributes
.size()) );
1527 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[5]) );
1528 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[5]) );
1530 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[6].mnParagraph
) );
1531 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs3
[6].mnStart
) );
1532 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs3
[6].mnEnd
) );
1533 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[6].maAttributes
.size()) );
1534 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[6]) );
1536 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[7].mnParagraph
) );
1537 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs3
[7].mnStart
) );
1538 CPPUNIT_ASSERT_EQUAL( 24, static_cast<int>(aAttrs3
[7].mnEnd
) );
1539 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[7].maAttributes
.size()) );
1541 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[8].mnParagraph
) );
1542 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[8].mnStart
) );
1543 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs3
[8].mnEnd
) );
1544 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[8].maAttributes
.size()) );
1546 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[9].mnParagraph
) );
1547 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs3
[9].mnStart
) );
1548 CPPUNIT_ASSERT_EQUAL( 29, static_cast<int>(aAttrs3
[9].mnEnd
) );
1549 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[9].maAttributes
.size()) );
1550 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[9]) );
1552 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[10].mnParagraph
) );
1553 CPPUNIT_ASSERT_EQUAL( 29, static_cast<int>(aAttrs3
[10].mnStart
) );
1554 CPPUNIT_ASSERT_EQUAL( 33, static_cast<int>(aAttrs3
[10].mnEnd
) );
1555 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[10].maAttributes
.size()) );
1556 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[10]) );
1557 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[10]) );
1559 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[11].mnParagraph
) );
1560 CPPUNIT_ASSERT_EQUAL( 33, static_cast<int>(aAttrs3
[11].mnStart
) );
1561 CPPUNIT_ASSERT_EQUAL( 38, static_cast<int>(aAttrs3
[11].mnEnd
) );
1562 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[11].maAttributes
.size()) );
1563 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[11]) );
1565 CPPUNIT_ASSERT_EQUAL( 3, static_cast<int>(aAttrs3
[12].mnParagraph
) );
1566 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[12].mnStart
) );
1567 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[12].mnEnd
) );
1568 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[12].maAttributes
.size()) );
1569 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[12]) );
1571 CPPUNIT_ASSERT_EQUAL( 3, static_cast<int>(aAttrs3
[13].mnParagraph
) );
1572 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[13].mnStart
) );
1573 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs3
[13].mnEnd
) );
1574 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[13].maAttributes
.size()) );
1575 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[13]) );
1576 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[13]) );
1578 CPPUNIT_ASSERT_EQUAL( 3, static_cast<int>(aAttrs3
[14].mnParagraph
) );
1579 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs3
[14].mnStart
) );
1580 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs3
[14].mnEnd
) );
1581 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[14].maAttributes
.size()) );
1582 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[14]) );
1585 void Test::testParaStartCopyPaste()
1587 // Create EditEngine's instance
1588 EditEngine
aEditEngine( mpItemPool
.get() );
1590 // Get EditDoc for current EditEngine's instance
1591 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
1593 // Initially no text should be there
1594 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
1595 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
1597 // Insert initial text
1598 OUString aFirstPara
= "This is first paragraph";
1599 // Selection Ref ........8..............
1600 OUString aSecondPara
= "This is second paragraph";
1601 // Selection Ref .............14.........
1602 OUString aThirdPara
= "This is third paragraph";
1603 OUString aText
= aFirstPara
+ "\n" + aSecondPara
+ "\n" + aThirdPara
;
1604 sal_Int32 aTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength() + aThirdPara
.getLength();
1605 aEditEngine
.SetText( aText
);
1606 OUString aCopyText
= "first paragraphThis is second";
1607 sal_Int32 aCopyTextLen
= aCopyText
.getLength();
1610 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
1611 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1612 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1613 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1615 // Copy initial text using legacy format
1616 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,8,1,14) );
1618 // Paste text at the start
1619 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetStartPaM(), true );
1622 OUString aSecondParaAfterCopyPaste
= "This is second" + aFirstPara
;
1623 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aCopyTextLen
, rDoc
.GetTextLen() );
1624 CPPUNIT_ASSERT_EQUAL( OUString("first paragraph"), rDoc
.GetParaAsString(sal_Int32(0)) );
1625 CPPUNIT_ASSERT_EQUAL( aSecondParaAfterCopyPaste
, rDoc
.GetParaAsString(sal_Int32(1)) );
1626 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1627 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(3)) );
1630 void Test::testSectionAttributes()
1632 EditEngine
aEngine(mpItemPool
.get());
1634 std::unique_ptr
<SfxItemSet
> pSet(new SfxItemSet(aEngine
.GetEmptyItemSet()));
1635 SvxWeightItem
aBold(WEIGHT_BOLD
, EE_CHAR_WEIGHT
);
1636 SvxPostureItem
aItalic(ITALIC_NORMAL
, EE_CHAR_ITALIC
);
1639 aEngine
.SetText("aaabbbccc");
1641 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be exactly one item.", static_cast<sal_uInt16
>(1), pSet
->Count());
1642 aEngine
.QuickSetAttribs(*pSet
, ESelection(0,0,0,6)); // 'aaabbb' - end point is not inclusive.
1643 pSet
.reset(new SfxItemSet(aEngine
.GetEmptyItemSet()));
1645 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be exactly one item.", static_cast<sal_uInt16
>(1), pSet
->Count());
1647 aEngine
.QuickSetAttribs(*pSet
, ESelection(0,3,0,9)); // 'bbbccc'
1648 std::unique_ptr
<EditTextObject
> pEditText(aEngine
.CreateTextObject());
1649 CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText
);
1650 std::vector
<editeng::Section
> aAttrs
;
1651 pEditText
->GetAllSections(aAttrs
);
1653 // Now, we should have a total of 3 sections.
1654 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be 3 sections.", static_cast<size_t>(3), aAttrs
.size());
1656 // First section should be 0-3 of paragraph 0, and it should only have boldness applied.
1657 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnParagraph
));
1658 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnStart
));
1659 CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(aAttrs
[0].mnEnd
));
1660 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[0].maAttributes
.size()));
1661 CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(aAttrs
[0]));
1663 // Second section should be 3-6, and it should be both bold and italic.
1664 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[1].mnParagraph
));
1665 CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(aAttrs
[1].mnStart
));
1666 CPPUNIT_ASSERT_EQUAL(6, static_cast<int>(aAttrs
[1].mnEnd
));
1667 CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(aAttrs
[1].maAttributes
.size()));
1668 CPPUNIT_ASSERT_MESSAGE("This section must be bold and italic.", hasBold(aAttrs
[1]));
1669 CPPUNIT_ASSERT_MESSAGE("This section must be bold and italic.", hasItalic(aAttrs
[1]));
1671 // Third section should be 6-9, and it should be only italic.
1672 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[2].mnParagraph
));
1673 CPPUNIT_ASSERT_EQUAL(6, static_cast<int>(aAttrs
[2].mnStart
));
1674 CPPUNIT_ASSERT_EQUAL(9, static_cast<int>(aAttrs
[2].mnEnd
));
1675 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[2].maAttributes
.size()));
1676 CPPUNIT_ASSERT_MESSAGE("This section must be italic.", hasItalic(aAttrs
[2]));
1680 // Set text consisting of 5 paragraphs with the 2nd and 4th paragraphs
1683 aEngine
.SetText("one\n\ntwo\n\nthree");
1684 sal_Int32 nParaCount
= aEngine
.GetParagraphCount();
1685 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), nParaCount
);
1687 // Apply boldness to paragraphs 1, 3, 5 only. Leave 2 and 4 unformatted.
1688 pSet
.reset(new SfxItemSet(aEngine
.GetEmptyItemSet()));
1690 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be exactly one item.", static_cast<sal_uInt16
>(1), pSet
->Count());
1691 aEngine
.QuickSetAttribs(*pSet
, ESelection(0,0,0,3));
1692 aEngine
.QuickSetAttribs(*pSet
, ESelection(2,0,2,3));
1693 aEngine
.QuickSetAttribs(*pSet
, ESelection(4,0,4,5));
1695 std::unique_ptr
<EditTextObject
> pEditText(aEngine
.CreateTextObject());
1696 CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText
);
1697 std::vector
<editeng::Section
> aAttrs
;
1698 pEditText
->GetAllSections(aAttrs
);
1699 CPPUNIT_ASSERT_EQUAL(size_t(5), aAttrs
.size());
1701 // 1st, 3rd and 5th sections should correspond with 1st, 3rd and 5th paragraphs.
1702 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnParagraph
));
1703 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnStart
));
1704 CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(aAttrs
[0].mnEnd
));
1705 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[0].maAttributes
.size()));
1706 CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(aAttrs
[0]));
1708 CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(aAttrs
[2].mnParagraph
));
1709 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[2].mnStart
));
1710 CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(aAttrs
[2].mnEnd
));
1711 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[2].maAttributes
.size()));
1712 CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(aAttrs
[2]));
1714 CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(aAttrs
[4].mnParagraph
));
1715 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[4].mnStart
));
1716 CPPUNIT_ASSERT_EQUAL(5, static_cast<int>(aAttrs
[4].mnEnd
));
1717 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[4].maAttributes
.size()));
1718 CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(aAttrs
[4]));
1720 // The 2nd and 4th paragraphs should be empty.
1721 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[1].mnParagraph
));
1722 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[1].mnStart
));
1723 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[1].mnEnd
));
1724 CPPUNIT_ASSERT_MESSAGE("Attribute array should be empty.", aAttrs
[1].maAttributes
.empty());
1726 CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(aAttrs
[3].mnParagraph
));
1727 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[3].mnStart
));
1728 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[3].mnEnd
));
1729 CPPUNIT_ASSERT_MESSAGE("Attribute array should be empty.", aAttrs
[3].maAttributes
.empty());
1735 aEngine
.SetText("one\ntwo");
1736 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(2), aEngine
.GetParagraphCount());
1738 // embolden 2nd paragraph
1739 pSet
.reset(new SfxItemSet(aEngine
.GetEmptyItemSet()));
1741 aEngine
.QuickSetAttribs(*pSet
, ESelection(1,0,1,3));
1742 // disboldify 1st paragraph
1743 SvxWeightItem
aNotSoBold(WEIGHT_NORMAL
, EE_CHAR_WEIGHT
);
1744 pSet
->Put(aNotSoBold
);
1745 aEngine
.QuickSetAttribs(*pSet
, ESelection(0,0,0,3));
1747 // now delete & join the paragraphs - this is fdo#85496 scenario
1748 aEngine
.QuickDelete(ESelection(0,0,1,3));
1749 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), aEngine
.GetParagraphCount());
1751 std::unique_ptr
<EditTextObject
> pEditText(aEngine
.CreateTextObject());
1752 CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText
);
1753 std::vector
<editeng::Section
> aAttrs
;
1754 pEditText
->GetAllSections(aAttrs
);
1756 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aAttrs
.size());
1758 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnParagraph
));
1759 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnStart
));
1760 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnEnd
));
1761 std::set
<sal_uInt16
> whiches
;
1762 for (size_t i
= 0; i
< aAttrs
[0].maAttributes
.size(); ++i
)
1764 sal_uInt16
const nWhich(aAttrs
[0].maAttributes
[i
]->Which());
1765 CPPUNIT_ASSERT_MESSAGE("duplicate item in text portion attributes",
1766 whiches
.insert(nWhich
).second
);
1771 void Test::testLargeParaCopyPaste()
1773 // Create EditEngine's instance
1774 EditEngine
aEditEngine( mpItemPool
.get() );
1776 // Get EditDoc for current EditEngine's instance
1777 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
1779 // Initially no text should be there
1780 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
1781 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
1783 // Insert initial text
1784 OUString aFirstPara
= "This is first paragraph";
1785 OUString aSecondPara
= "This is second paragraph";
1786 OUString aThirdPara
= "This is third paragraph";
1787 OUString aFourthPara
= "This is fourth paragraph";
1788 OUString aFifthPara
= "This is fifth paragraph";
1789 OUString aSixthPara
= "This is sixth paragraph";
1790 //Positions Ref: ........*8.............
1791 OUString aSeventhPara
= "This is seventh paragraph";
1792 OUString aEighthPara
= "This is eighth paragraph";
1793 //Positions Ref: .............*13
1794 OUString aNinthPara
= "This is ninth paragraph";
1795 OUString aTenthPara
= "This is tenth paragraph";
1796 OUString aText
= aFirstPara
+ "\n" + aSecondPara
+ "\n" + aThirdPara
+ "\n" +
1797 aFourthPara
+ "\n" + aFifthPara
+ "\n" + aSixthPara
+ "\n" + aSeventhPara
+ "\n" +
1798 aEighthPara
+ "\n" + aNinthPara
+ "\n" + aTenthPara
;
1799 sal_Int32 aTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength() + aThirdPara
.getLength() +
1800 aFourthPara
.getLength() + aFifthPara
.getLength() + aSixthPara
.getLength() +
1801 aSeventhPara
.getLength() + aEighthPara
.getLength() + aNinthPara
.getLength() + aTenthPara
.getLength();
1802 aEditEngine
.SetText( aText
);
1803 OUString aCopyText
= "sixth paragraphThis is seventh paragraphThis is eighth";
1804 sal_Int32 aCopyTextLen
= aCopyText
.getLength();
1807 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
1808 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1809 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1810 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1811 CPPUNIT_ASSERT_EQUAL( aFourthPara
, rDoc
.GetParaAsString(sal_Int32(3)) );
1812 CPPUNIT_ASSERT_EQUAL( aFifthPara
, rDoc
.GetParaAsString(sal_Int32(4)) );
1813 CPPUNIT_ASSERT_EQUAL( aSixthPara
, rDoc
.GetParaAsString(sal_Int32(5)) );
1814 CPPUNIT_ASSERT_EQUAL( aSeventhPara
, rDoc
.GetParaAsString(sal_Int32(6)) );
1815 CPPUNIT_ASSERT_EQUAL( aEighthPara
, rDoc
.GetParaAsString(sal_Int32(7)) );
1816 CPPUNIT_ASSERT_EQUAL( aNinthPara
, rDoc
.GetParaAsString(sal_Int32(8)) );
1817 CPPUNIT_ASSERT_EQUAL( aTenthPara
, rDoc
.GetParaAsString(sal_Int32(9)) );
1819 // Copy initial text using legacy format
1820 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(5,8,7,14) );
1822 // Paste text at the end of 4th Para
1823 ContentNode
* pLastNode
= rDoc
.GetObject(3);
1824 aEditEngine
.InsertText( xData
, OUString(), EditPaM( pLastNode
, pLastNode
->Len() ), true );
1827 OUString aFourthParaAfterCopyPaste
= aFourthPara
+ "sixth paragraph";
1828 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aCopyTextLen
, rDoc
.GetTextLen() );
1829 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1830 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1831 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1832 CPPUNIT_ASSERT_EQUAL( aFourthParaAfterCopyPaste
, rDoc
.GetParaAsString(sal_Int32(3)) );
1833 CPPUNIT_ASSERT_EQUAL( aSeventhPara
, rDoc
.GetParaAsString(sal_Int32(4)) );
1834 CPPUNIT_ASSERT_EQUAL( OUString("This is eighth"), rDoc
.GetParaAsString(sal_Int32(5)) );
1835 CPPUNIT_ASSERT_EQUAL( aFifthPara
, rDoc
.GetParaAsString(sal_Int32(6)) );
1836 CPPUNIT_ASSERT_EQUAL( aSixthPara
, rDoc
.GetParaAsString(sal_Int32(7)) );
1837 CPPUNIT_ASSERT_EQUAL( aSeventhPara
, rDoc
.GetParaAsString(sal_Int32(8)) );
1838 CPPUNIT_ASSERT_EQUAL( aEighthPara
, rDoc
.GetParaAsString(sal_Int32(9)) );
1839 CPPUNIT_ASSERT_EQUAL( aNinthPara
, rDoc
.GetParaAsString(sal_Int32(10)) );
1840 CPPUNIT_ASSERT_EQUAL( aTenthPara
, rDoc
.GetParaAsString(sal_Int32(11)) );
1843 OUString
lcl_translitTest(EditEngine
& aEditEngine
, const OUString
& text
, const ESelection
& esel
, const TransliterationFlags nType
)
1845 aEditEngine
.SetText(text
);
1846 aEditEngine
.TransliterateText(esel
, nType
);
1847 return aEditEngine
.GetText();
1851 void Test::testTransliterate()
1853 // Create EditEngine's instance
1854 EditEngine
editEng( mpItemPool
.get() );
1856 OUString
sText("one (two) three");
1857 editEng
.SetText(sText
);
1858 editEng
.TransliterateText(ESelection(0, 0, 0, sText
.getLength()), TransliterationFlags::TITLE_CASE
);
1859 CPPUNIT_ASSERT_EQUAL(OUString("One (Two) Three"), editEng
.GetText());
1861 using TF
= TransliterationFlags
;
1862 constexpr OUString sText2
= u
"Mary Jones met joe Smith. Time Passed."_ustr
;
1865 ESelection
esel(0, selStart
, 0, selEnd
);
1866 ESelection
eSentenSel(0, 0, 0, 25);
1868 /* DocumentContentOperationsManager checks if the cursor is inside of a word before transliterating,
1869 * but Edit Engine has no such check. Therefore, behavior is different between these two when the
1870 * cursor is on a word boundary. */
1872 /* No selection tests. Cursor between the ' ' and 'm' before 'met' - except in SENTENCE_CASE where the complete sentence is selected.*/
1873 CPPUNIT_ASSERT_EQUAL(OUString(""), editEng
.GetText(esel
));
1874 CPPUNIT_ASSERT_EQUAL(OUString("Mary jones met joe smith. Time Passed."), lcl_translitTest(editEng
, sText2
, eSentenSel
, TF::SENTENCE_CASE
));
1875 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1876 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MET joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1877 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1879 /* No selection tests. Cursor between the 't' and the ' ' after 'met'. */
1882 esel
= ESelection(0, selStart
, 0, selEnd
);
1883 CPPUNIT_ASSERT_EQUAL(OUString(""), editEng
.GetText(esel
));
1884 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1885 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MET joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1886 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1888 /* No selection tests. Cursor between the 'h' and the '.' after 'Smith'. */
1891 esel
= ESelection(0, selStart
, 0, selEnd
);
1892 CPPUNIT_ASSERT_EQUAL(OUString(""), editEng
.GetText(esel
));
1893 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1894 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1895 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1897 /* No selection tests. Cursor between the 'm' and 'e' in 'met'. */
1900 esel
= ESelection(0, selStart
, 0, selEnd
);
1901 CPPUNIT_ASSERT_EQUAL(OUString(""), editEng
.GetText(esel
));
1902 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1903 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MET joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1904 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1906 /* Test behavior when there is a selection that does not cross a word boundary: "met" */
1909 esel
= ESelection(0, selStart
, 0, selEnd
);
1910 CPPUNIT_ASSERT_EQUAL(OUString("met"), editEng
.GetText(esel
));
1911 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1912 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MET joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1913 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1915 /* Test behavior when there is a selection that does not begin at a word boundary: "et" */
1918 esel
= ESelection(0, selStart
, 0, selEnd
);
1919 CPPUNIT_ASSERT_EQUAL(OUString("et"), editEng
.GetText(esel
));
1920 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mEt joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1921 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mET joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1922 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1924 /* Test behavior when there is a selection that ends in the middle of a word */
1927 esel
= ESelection(0, selStart
, 0, selEnd
);
1928 CPPUNIT_ASSERT_EQUAL(OUString("me"), editEng
.GetText(esel
));
1929 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1930 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MEt joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1931 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1934 /* Test behavior when there is a selection that crosses a word boundary: "nes met joe Sm" */
1937 esel
= ESelection(0, selStart
, 0, selEnd
);
1938 CPPUNIT_ASSERT_EQUAL(OUString("nes met joe Sm"), editEng
.GetText(esel
));
1939 CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNes met joe smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1940 CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNes Met Joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1941 CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNES MET JOE SMith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1942 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1944 /* Test behavior when there is a selection that crosses a sentence boundary: "joe Smith. Time Passed." */
1947 esel
= ESelection(0, selStart
, 0, selEnd
);
1948 editEng
.SetText(sText2
);
1949 CPPUNIT_ASSERT_EQUAL(OUString("joe Smith. Time Passed."), editEng
.GetText(esel
));
1951 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met Joe smith. Time passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1952 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met Joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1953 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met JOE SMITH. TIME PASSED."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1954 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe smith. time passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1956 /* Test behavior when sentence ends with a capital that is not selected: "CURRENT IS EQUAL TO 10 A" */
1959 esel
= ESelection(0, selStart
, 0, selEnd
);
1960 constexpr OUString
sText3(u
"CURRENT IS EQUAL TO 10 A"_ustr
);
1961 editEng
.SetText(sText3
);
1962 CPPUNIT_ASSERT_EQUAL(OUString("CURRENT IS EQUAL TO"), editEng
.GetText(esel
));
1964 CPPUNIT_ASSERT_EQUAL(OUString("Current is equal to 10 A"), lcl_translitTest(editEng
, sText3
, esel
, TF::SENTENCE_CASE
));
1965 CPPUNIT_ASSERT_EQUAL(OUString("Current Is Equal To 10 A"), lcl_translitTest(editEng
, sText3
, esel
, TF::TITLE_CASE
));
1966 CPPUNIT_ASSERT_EQUAL(OUString("CURRENT IS EQUAL TO 10 A"), lcl_translitTest(editEng
, sText3
, esel
, TF::LOWERCASE_UPPERCASE
));
1967 CPPUNIT_ASSERT_EQUAL(OUString("current is equal to 10 A"), lcl_translitTest(editEng
, sText3
, esel
, TF::UPPERCASE_LOWERCASE
));
1971 void Test::testTdf147196()
1973 EditEngine
editEng( mpItemPool
.get() );
1974 editEng
.SetText("2.2 Publication of information - CAA\nSection 4.2 of a CA\'s Certificate Policy and/or Certification Practice Statement SHALL state the CA\'s policy or practice on processing CAA Records for Fully Qualified Domain Names; that policy shall be consistent with these Requirements. \n\nIt shall clearly specify the set of Issuer Domain Names that the CA recognises in CAA \"issue\" or \"issuewild\" records as permitting it to issue. The CA SHALL log all actions taken, if any, consistent with its processing practice.");
1975 editEng
.TransliterateText(ESelection(0, 0, 3, 232), TransliterationFlags::TITLE_CASE
);
1976 CPPUNIT_ASSERT_EQUAL(OUString("2.2 Publication Of Information - Caa\nSection 4.2 Of A Ca\'s Certificate Policy And/Or Certification Practice Statement Shall State The Ca\'s Policy Or Practice On Processing Caa Records For Fully Qualified Domain Names; That Policy Shall Be Consistent With These Requirements. \n\nIt Shall Clearly Specify The Set Of Issuer Domain Names That The Ca Recognises In Caa \"Issue\" Or \"Issuewild\" Records As Permitting It To Issue. The Ca Shall Log All Actions Taken, If Any, Consistent With Its Processing Practice."), editEng
.GetText());
1979 void Test::testTdf148148()
1981 using TF
= TransliterationFlags
;
1982 EditEngine
editEng( mpItemPool
.get() );
1984 /* Test what happens when node contains text but selection does not contain any text */
1987 ESelection
esel(0, selStart
, 0, selEnd
);
1988 constexpr OUString
sText1(u
" text"_ustr
);
1989 editEng
.SetText(sText1
);
1990 CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng
.GetText(esel
));
1992 CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng
, sText1
, esel
, TF::SENTENCE_CASE
));
1993 CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng
, sText1
, esel
, TF::TITLE_CASE
));
1994 CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng
, sText1
, esel
, TF::LOWERCASE_UPPERCASE
));
1995 CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng
, sText1
, esel
, TF::UPPERCASE_LOWERCASE
));
1999 esel
= ESelection(0, selStart
, 0, selEnd
);
2000 constexpr OUString
sText2(u
"text "_ustr
);
2001 editEng
.SetText(sText2
);
2002 CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng
.GetText(esel
));
2004 CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
2005 CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
2006 CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
2007 CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
2009 /* Test what happens when node contains only non-word text but selection does not contain any text */
2012 esel
= ESelection(0, selStart
, 0, selEnd
);
2013 constexpr OUString
sText3(u
" -1"_ustr
);
2014 editEng
.SetText(sText3
);
2015 CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng
.GetText(esel
));
2017 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText3
, esel
, TF::SENTENCE_CASE
));
2018 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText3
, esel
, TF::TITLE_CASE
));
2019 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText3
, esel
, TF::LOWERCASE_UPPERCASE
));
2020 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText3
, esel
, TF::UPPERCASE_LOWERCASE
));
2024 esel
= ESelection(0, selStart
, 0, selEnd
);
2025 constexpr OUString
sText4(u
"-1 "_ustr
);
2026 editEng
.SetText(sText4
);
2027 CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng
.GetText(esel
));
2029 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText4
, esel
, TF::SENTENCE_CASE
));
2030 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText4
, esel
, TF::TITLE_CASE
));
2031 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText4
, esel
, TF::LOWERCASE_UPPERCASE
));
2032 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText4
, esel
, TF::UPPERCASE_LOWERCASE
));
2034 /* Test what happens when node and selection contains only non-word text */
2037 esel
= ESelection(0, selStart
, 0, selEnd
);
2038 constexpr OUString
sText5(u
" -1"_ustr
);
2039 editEng
.SetText(sText3
);
2040 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), editEng
.GetText(esel
));
2042 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText5
, esel
, TF::SENTENCE_CASE
));
2043 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText5
, esel
, TF::TITLE_CASE
));
2044 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText5
, esel
, TF::LOWERCASE_UPPERCASE
));
2045 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText5
, esel
, TF::UPPERCASE_LOWERCASE
));
2049 esel
= ESelection(0, selStart
, 0, selEnd
);
2050 constexpr OUString
sText6(u
"-1 "_ustr
);
2051 editEng
.SetText(sText4
);
2052 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), editEng
.GetText(esel
));
2054 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText6
, esel
, TF::SENTENCE_CASE
));
2055 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText6
, esel
, TF::TITLE_CASE
));
2056 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText6
, esel
, TF::LOWERCASE_UPPERCASE
));
2057 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText6
, esel
, TF::UPPERCASE_LOWERCASE
));
2062 void Test::testSingleLine()
2064 EditEngine
aEditEngine( mpItemPool
.get() );
2066 aEditEngine
.SetSingleLine(true);
2067 aEditEngine
.SetText("Bolivian\nSanta Cruz de la Sierra");
2068 aEditEngine
.QuickFormatDoc(true);
2069 CPPUNIT_ASSERT_EQUAL(true, aEditEngine
.IsFormatted());
2070 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aEditEngine
.GetParagraphCount());
2071 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aEditEngine
.GetLineCount(0));
2074 CPPUNIT_TEST_SUITE_REGISTRATION(Test
);
2078 CPPUNIT_PLUGIN_IMPLEMENT();
2080 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */