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 <editeng/fontitem.hxx>
33 #include <editeng/fhgtitem.hxx>
35 #include <com/sun/star/text/textfield/Type.hpp>
38 #include <editeng/outliner.hxx>
40 using namespace com::sun::star
;
44 class Test
: public test::BootstrapFixture
49 virtual void setUp() override
;
50 virtual void tearDown() override
;
53 /// Test text portions position when percentage line spacing is set
54 void testLineSpacing();
57 void testConstruction();
59 /// Test UNO service class that implements text field items.
60 void testUnoTextFields();
63 void testAutocorrect();
65 /// Test Copy/Paste with hyperlinks in text using Legacy Format
66 void testHyperlinkCopyPaste();
68 /// Test Copy/Paste using Legacy Format
71 /// Test Copy/Paste with selective selection over multiple paragraphs
72 void testMultiParaSelCopyPaste();
74 /// Test Copy/Paste with Tabs
75 void testTabsCopyPaste();
78 void testHyperlinkSearch();
80 /// Test Copy/Paste with Bold/Italic text using Legacy Format
81 void testBoldItalicCopyPaste();
83 /// Test Copy/Paste with Underline text using Legacy Format
84 void testUnderlineCopyPaste();
86 /// Test Copy/Paste with multiple paragraphs
87 void testMultiParaCopyPaste();
89 /// Test Copy/Paste with multiple paragraphs having Bold/Italic text
90 void testParaBoldItalicCopyPaste();
92 void testParaStartCopyPaste();
94 void testSectionAttributes();
96 void testLargeParaCopyPaste();
98 void testTransliterate();
100 void testTdf147196();
102 void testTdf148148();
104 void testSingleLine();
106 DECL_STATIC_LINK( Test
, CalcFieldValueHdl
, EditFieldInfo
*, void );
108 CPPUNIT_TEST_SUITE(Test
);
110 CPPUNIT_TEST(testLineSpacing
);
112 CPPUNIT_TEST(testConstruction
);
113 CPPUNIT_TEST(testUnoTextFields
);
114 CPPUNIT_TEST(testAutocorrect
);
115 CPPUNIT_TEST(testHyperlinkCopyPaste
);
116 CPPUNIT_TEST(testCopyPaste
);
117 CPPUNIT_TEST(testMultiParaSelCopyPaste
);
118 CPPUNIT_TEST(testTabsCopyPaste
);
119 CPPUNIT_TEST(testHyperlinkSearch
);
120 CPPUNIT_TEST(testBoldItalicCopyPaste
);
121 CPPUNIT_TEST(testUnderlineCopyPaste
);
122 CPPUNIT_TEST(testMultiParaCopyPaste
);
123 CPPUNIT_TEST(testParaBoldItalicCopyPaste
);
124 CPPUNIT_TEST(testParaStartCopyPaste
);
125 CPPUNIT_TEST(testSectionAttributes
);
126 CPPUNIT_TEST(testLargeParaCopyPaste
);
127 CPPUNIT_TEST(testTransliterate
);
128 CPPUNIT_TEST(testTdf147196
);
129 CPPUNIT_TEST(testTdf148148
);
130 CPPUNIT_TEST(testSingleLine
);
131 CPPUNIT_TEST_SUITE_END();
134 rtl::Reference
<EditEngineItemPool
> mpItemPool
;
141 test::BootstrapFixture::setUp();
143 mpItemPool
= new EditEngineItemPool();
145 SfxApplication::GetOrCreate();
148 void Test::tearDown()
151 test::BootstrapFixture::tearDown();
155 void Test::testLineSpacing()
157 // Create EditEngine's instance
158 EditEngine
aEditEngine(mpItemPool
.get());
160 if(aEditEngine
.GetRefDevice()->GetDPIY() != 96
161 || aEditEngine
.GetRefDevice()->GetDPIScaleFactor() != 1.0)
164 // Get EditDoc for current EditEngine's instance
165 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
167 // Initially no text should be there
168 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rDoc
.GetTextLen());
169 CPPUNIT_ASSERT_EQUAL(OUString(), rDoc
.GetParaAsString(sal_Int32(0)));
172 OUString aText
= "This is multi-line paragraph";
174 sal_Int32 aTextLen
= aText
.getLength();
175 aEditEngine
.SetText(aText
);
177 // Assert changes - text insertion
178 CPPUNIT_ASSERT_EQUAL(aTextLen
, rDoc
.GetTextLen());
179 CPPUNIT_ASSERT_EQUAL(aText
, rDoc
.GetParaAsString(sal_Int32(0)));
181 // Select all paragraphs
182 ESelection
aSelection(0, 0, 0, aTextLen
);
184 auto doTest
= [&](sal_uInt16 nSpace
, sal_uInt16 nExpMaxAscent
, sal_uInt32 nExpLineHeight
)
186 std::unique_ptr
<SfxItemSet
> pSet(new SfxItemSet(aEditEngine
.GetEmptyItemSet()));
187 SvxLineSpacingItem
aLineSpacing(LINE_SPACE_DEFAULT_HEIGHT
, EE_PARA_SBL
);
188 aLineSpacing
.SetPropLineSpace(nSpace
);
189 pSet
->Put(aLineSpacing
);
192 SvxFontItem
aFont(EE_CHAR_FONTINFO
);
193 aFont
.SetFamilyName("Liberation Sans");
195 SvxFontHeightItem
aFontSize(240, 100, EE_CHAR_FONTHEIGHT
);
196 pSet
->Put(aFontSize
);
198 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(3), pSet
->Count());
200 aEditEngine
.QuickSetAttribs(*pSet
, aSelection
);
203 ParaPortion
* pParaPortion
= aEditEngine
.GetParaPortions()[0];
204 ContentNode
* const pNode
= pParaPortion
->GetNode();
205 const SvxLineSpacingItem
& rLSItem
= pNode
->GetContentAttribs().GetItem(EE_PARA_SBL
);
206 CPPUNIT_ASSERT_EQUAL(SvxInterLineSpaceRule::Prop
, rLSItem
.GetInterLineSpaceRule());
207 CPPUNIT_ASSERT_EQUAL(nSpace
, rLSItem
.GetPropLineSpace());
209 // Check the first line
210 ParagraphInfos aInfo
= aEditEngine
.GetParagraphInfos(0);
211 CPPUNIT_ASSERT_EQUAL(nExpMaxAscent
, aInfo
.nFirstLineMaxAscent
);
212 CPPUNIT_ASSERT_EQUAL(nExpLineHeight
, aEditEngine
.GetLineHeight(0));
215 // Test first case - 60%
216 doTest(60, 122, 153);
218 // Force multiple lines
219 aEditEngine
.SetPaperSize(Size(1000, 6000));
220 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aEditEngine
.GetLineCount(0));
222 // Test second case - 150%
223 doTest(150, 337, 382);
225 // Test lower Word limit - 6% (factor 0.06)
228 // Test upper Word limit - 13200% (factor 132)
229 doTest(13200, 33615, 33660);
233 void Test::testConstruction()
235 EditEngine
aEngine(mpItemPool
.get());
237 aEngine
.SetText("I am Edit Engine.");
240 bool includes(const uno::Sequence
<OUString
>& rSeq
, std::u16string_view rVal
)
242 for (OUString
const & s
: rSeq
)
249 void Test::testUnoTextFields()
253 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::DATE
));
254 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
255 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.DateTime");
256 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
261 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::URL
));
262 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
263 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.URL");
264 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
269 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::PAGE
));
270 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
271 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.PageNumber");
272 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
277 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::PAGES
));
278 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
279 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.PageCount");
280 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
285 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::TIME
));
286 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
287 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.DateTime");
288 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
293 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::DOCINFO_TITLE
));
294 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
295 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.docinfo.Title");
296 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
301 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::TABLE
));
302 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
303 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.SheetName");
304 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
309 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::EXTENDED_TIME
));
310 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
311 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.DateTime");
312 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
317 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::EXTENDED_FILE
));
318 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
319 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.FileName");
320 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
325 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::AUTHOR
));
326 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
327 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.Author");
328 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
333 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::MEASURE
));
334 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
335 bool bGood
= includes(aSvcs
, u
"com.sun.star.text.textfield.Measure");
336 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
340 // PRESENTATION HEADER
341 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::PRESENTATION_HEADER
));
342 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
343 bool bGood
= includes(aSvcs
, u
"com.sun.star.presentation.textfield.Header");
344 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
348 // PRESENTATION FOOTER
349 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::PRESENTATION_FOOTER
));
350 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
351 bool bGood
= includes(aSvcs
, u
"com.sun.star.presentation.textfield.Footer");
352 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
356 // PRESENTATION DATE TIME
357 rtl::Reference
<SvxUnoTextField
> xField(new SvxUnoTextField(text::textfield::Type::PRESENTATION_DATE_TIME
));
358 uno::Sequence
<OUString
> aSvcs
= xField
->getSupportedServiceNames();
359 bool bGood
= includes(aSvcs
, u
"com.sun.star.presentation.textfield.DateTime");
360 CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood
);
364 class TestAutoCorrDoc
: public SvxAutoCorrDoc
367 /// just like the real thing, this dummy modifies the rText parameter :(
368 TestAutoCorrDoc(OUString
&rText
, LanguageType eLang
)
373 OUString
const& getResult() const
379 LanguageType m_eLang
;
380 virtual bool Delete( sal_Int32 nStt
, sal_Int32 nEnd
) override
382 //fprintf(stderr, "TestAutoCorrDoc::Delete\n");
383 m_rText
= m_rText
.replaceAt(nStt
, nEnd
-nStt
, u
"");
386 virtual bool Insert( sal_Int32 nPos
, const OUString
& rTxt
) override
388 //fprintf(stderr, "TestAutoCorrDoc::Insert\n");
389 m_rText
= m_rText
.replaceAt(nPos
, 0, rTxt
);
392 virtual bool Replace( sal_Int32 nPos
, const OUString
& rTxt
) override
394 //fprintf(stderr, "TestAutoCorrDoc::Replace\n");
395 return ReplaceRange( nPos
, rTxt
.getLength(), rTxt
);
397 virtual bool ReplaceRange( sal_Int32 nPos
, sal_Int32 nLen
, const OUString
& rTxt
) override
399 //fprintf(stderr, "TestAutoCorrDoc::ReplaceRange %d %d %s\n", nPos, nLen, OUStringToOString(rTxt, RTL_TEXTENCODING_UTF8).getStr());
400 m_rText
= m_rText
.replaceAt(nPos
, nLen
, rTxt
);
403 virtual void SetAttr( sal_Int32
, sal_Int32
, sal_uInt16
, SfxPoolItem
& ) override
405 //fprintf(stderr, "TestAutoCorrDoc::SetAttr\n");
407 virtual bool SetINetAttr( sal_Int32
, sal_Int32
, const OUString
& ) override
409 //fprintf(stderr, "TestAutoCorrDoc::SetINetAttr\n");
412 virtual OUString
const* GetPrevPara(bool) override
414 //fprintf(stderr, "TestAutoCorrDoc::GetPrevPara\n");
417 virtual bool ChgAutoCorrWord( sal_Int32
& rSttPos
,
418 sal_Int32 nEndPos
, SvxAutoCorrect
& rACorrect
,
419 OUString
* pPara
) override
421 //fprintf(stderr, "TestAutoCorrDoc::ChgAutoCorrWord\n");
423 if (m_rText
.isEmpty())
426 LanguageTag
aLanguageTag( m_eLang
);
427 const SvxAutocorrWord
* pFnd
= rACorrect
.SearchWordsInList(
428 m_rText
, rSttPos
, nEndPos
, *this, aLanguageTag
);
429 if (pFnd
&& pFnd
->IsTextOnly())
431 m_rText
= m_rText
.replaceAt(rSttPos
, nEndPos
, pFnd
->GetLong());
433 pPara
->clear(); // =&pCurNode->GetString();
439 virtual bool TransliterateRTLWord( sal_Int32
& /*rSttPos*/,
440 sal_Int32
/*nEndPos*/, bool /*bApply*/ ) override
446 //https://bugs.libreoffice.org/show_bug.cgi?id=55693
447 //Two capitalized letters are not corrected if dash or slash are directly
448 //before the two letters
449 void Test::testAutocorrect()
451 SvxAutoCorrect
aAutoCorrect((OUString()), (OUString()));
454 OUString
sInput("TEst-TEst");
455 sal_Unicode
const cNextChar(' ');
456 bool bNbspRunNext
= false;
458 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
459 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
461 CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", OUString("Test-Test "), aFoo
.getResult());
465 OUString
sInput("TEst/TEst");
466 sal_Unicode
const cNextChar(' ');
467 bool bNbspRunNext
= false;
469 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
470 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
472 CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", OUString("Test/Test "), aFoo
.getResult());
476 // test auto-bolding with '*'
477 OUString
sInput("*foo");
478 sal_Unicode
const cNextChar('*');
479 bool bNbspRunNext
= false;
481 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
482 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
484 CPPUNIT_ASSERT_EQUAL(OUString("foo"), aFoo
.getResult());
488 OUString
sInput("Test. test");
489 sal_Unicode
const cNextChar(' ');
490 bool bNbspRunNext
= false;
492 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
493 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
495 CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", OUString("Test. Test "), aFoo
.getResult());
498 // don't autocapitalize after a field mark
500 OUString
sInput("Test. \x01 test");
501 sal_Unicode
const cNextChar(' ');
502 bool bNbspRunNext
= false;
504 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
505 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
507 CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", OUString("Test. \x01 test "), aFoo
.getResult());
510 // consider field contents as text for auto quotes
512 OUString
sInput("T\x01");
513 sal_Unicode
const cNextChar('"');
514 static constexpr OUStringLiteral sExpected
= u
"T\x01\u201d";
515 bool bNbspRunNext
= false;
517 TestAutoCorrDoc
aFoo(sInput
, LANGUAGE_ENGLISH_US
);
518 aAutoCorrect
.SetAutoCorrFlag(ACFlags::ChgQuotes
, true);
519 aAutoCorrect
.DoAutoCorrect(aFoo
, sInput
, sInput
.getLength(), cNextChar
, true, bNbspRunNext
);
520 fprintf(stderr
, "text is %x\n", aFoo
.getResult()[aFoo
.getResult().getLength() - 1]);
522 CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", OUString(sExpected
), aFoo
.getResult());
527 IMPL_STATIC_LINK( Test
, CalcFieldValueHdl
, EditFieldInfo
*, pInfo
, void )
532 const SvxFieldItem
& rField
= pInfo
->GetField();
533 const SvxFieldData
* pField
= rField
.GetField();
534 if (const SvxURLField
* pURLField
= dynamic_cast<const SvxURLField
*>(pField
))
537 OUString aURL
= pURLField
->GetURL();
538 switch ( pURLField
->GetFormat() )
540 case SvxURLFormat::AppDefault
:
541 case SvxURLFormat::Repr
:
543 pInfo
->SetRepresentation( pURLField
->GetRepresentation() );
547 case SvxURLFormat::Url
:
549 pInfo
->SetRepresentation( aURL
);
556 OSL_FAIL("Unknown Field");
557 pInfo
->SetRepresentation(OUString('?'));
561 void Test::testHyperlinkCopyPaste()
563 // Create Outliner instance
564 Outliner
aOutliner(mpItemPool
.get(), OutlinerMode
566 aOutliner
.SetCalcFieldValueHdl( LINK( nullptr, Test
, CalcFieldValueHdl
) );
568 // Create EditEngine's instance
569 EditEngine
& aEditEngine
= const_cast<EditEngine
&> (aOutliner
.GetEditEngine());
571 // Get EditDoc for current EditEngine's instance
572 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
574 // New instance must be empty - no initial text
575 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
576 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
578 // Get corresponding Field Item for inserting URLs in text
580 OUString aURL1
= "mailto:///user@example.com";
581 OUString aRepres1
= "user@example.com";
582 SvxURLField
aURLField1( aURL1
, aRepres1
, SvxURLFormat::Repr
);
583 SvxFieldItem
aField1( aURLField1
, EE_FEATURE_FIELD
);
585 OUString aURL2
= "mailto:///example@domain.com";
586 OUString aRepres2
= "example@domain.com";
587 SvxURLField
aURLField2( aURL2
, aRepres2
, SvxURLFormat::Repr
);
588 SvxFieldItem
aField2( aURLField2
, EE_FEATURE_FIELD
);
590 // Insert initial text
591 OUString aParaText
= "sampletextfortestingfeaturefields";
592 // Positions Ref .............*13....*20..........
593 sal_Int32 aTextLen
= aParaText
.getLength();
594 aEditEngine
.SetText( aParaText
);
597 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
598 CPPUNIT_ASSERT_EQUAL( aParaText
, rDoc
.GetParaAsString(sal_Int32(0)) );
601 ContentNode
*pNode
= rDoc
.GetObject(0);
602 EditSelection
aSel1( EditPaM(pNode
, 13), EditPaM(pNode
, 13) );
603 aEditEngine
.InsertField( aSel1
, aField1
);
605 // Assert Field Count
606 CPPUNIT_ASSERT_EQUAL( sal_uInt16(1), aEditEngine
.GetFieldCount(0) );
609 EditSelection
aSel2( EditPaM(pNode
, 20 + 1), EditPaM(pNode
, 20 + 1) );
610 aEditEngine
.InsertField( aSel2
, aField2
);
612 // Assert Field Count
613 CPPUNIT_ASSERT_EQUAL( sal_uInt16(2), aEditEngine
.GetFieldCount(0) );
615 // Assert URL Fields and text before copy
617 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aRepres1
.getLength() + aRepres2
.getLength(), rDoc
.GetTextLen() );
618 CPPUNIT_ASSERT_EQUAL( OUString("sampletextforuser@example.comtestingexample@domain.comfeaturefields"), rDoc
.GetParaAsString(sal_Int32(0)) );
621 EFieldInfo aURLFieldInfo1
= aEditEngine
.GetFieldInfo( sal_Int32(0), sal_uInt16(0) );
622 CPPUNIT_ASSERT_EQUAL( sal_Int32(13), aURLFieldInfo1
.aPosition
.nIndex
);
623 CPPUNIT_ASSERT_EQUAL( sal_uInt16(EE_FEATURE_FIELD
), aURLFieldInfo1
.pFieldItem
->Which() );
624 SvxURLField
* pURLField1
= dynamic_cast<SvxURLField
*> ( const_cast<SvxFieldData
*> (aURLFieldInfo1
.pFieldItem
->GetField()) );
625 CPPUNIT_ASSERT(pURLField1
);
626 CPPUNIT_ASSERT_EQUAL( aURL1
, pURLField1
->GetURL() );
627 CPPUNIT_ASSERT_EQUAL( aRepres1
, pURLField1
->GetRepresentation() );
630 EFieldInfo aURLFieldInfo2
= aEditEngine
.GetFieldInfo( sal_Int32(0), sal_uInt16(1) );
631 CPPUNIT_ASSERT_EQUAL( sal_Int32(21), aURLFieldInfo2
.aPosition
.nIndex
);
632 CPPUNIT_ASSERT_EQUAL( sal_uInt16(EE_FEATURE_FIELD
), aURLFieldInfo2
.pFieldItem
->Which() );
633 SvxURLField
* pURLField2
= dynamic_cast<SvxURLField
*> ( const_cast<SvxFieldData
*> (aURLFieldInfo2
.pFieldItem
->GetField()) );
634 CPPUNIT_ASSERT(pURLField2
);
635 CPPUNIT_ASSERT_EQUAL( aURL2
, pURLField2
->GetURL() );
636 CPPUNIT_ASSERT_EQUAL( aRepres2
, pURLField2
->GetRepresentation() );
638 // Copy text using legacy format
639 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,10,0,21) );
641 // Paste text at the end
642 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
644 // Assert Changes ACP, ACP: after Copy/Paste
646 // Check the fields count
647 CPPUNIT_ASSERT_EQUAL( sal_uInt16(3), aEditEngine
.GetFieldCount(0) );
649 // Check the updated text length
650 CPPUNIT_ASSERT_EQUAL( aTextLen
+ 10 + aRepres1
.getLength()*2 + aRepres2
.getLength(), rDoc
.GetTextLen() );
652 // Check the updated text contents
653 CPPUNIT_ASSERT_EQUAL( OUString("sampletextforuser@example.comtestingexample@domain.comfeaturefieldsforuser@example.comtesting"), rDoc
.GetParaAsString(sal_Int32(0)) );
655 // Check the Fields and their values
658 EFieldInfo aACPURLFieldInfo1
= aEditEngine
.GetFieldInfo( sal_Int32(0), sal_uInt16(0) );
659 CPPUNIT_ASSERT_EQUAL( sal_Int32(13), aACPURLFieldInfo1
.aPosition
.nIndex
);
660 CPPUNIT_ASSERT_EQUAL( sal_uInt16(EE_FEATURE_FIELD
), aACPURLFieldInfo1
.pFieldItem
->Which() );
661 SvxURLField
* pACPURLField1
= dynamic_cast<SvxURLField
*> ( const_cast<SvxFieldData
*> (aACPURLFieldInfo1
.pFieldItem
->GetField()) );
662 CPPUNIT_ASSERT(pACPURLField1
);
663 CPPUNIT_ASSERT_EQUAL( aURL1
, pACPURLField1
->GetURL() );
664 CPPUNIT_ASSERT_EQUAL( aRepres1
, pACPURLField1
->GetRepresentation() );
667 EFieldInfo aACPURLFieldInfo2
= aEditEngine
.GetFieldInfo( sal_Int32(0), sal_uInt16(1) );
668 CPPUNIT_ASSERT_EQUAL( sal_Int32(21), aACPURLFieldInfo2
.aPosition
.nIndex
);
669 CPPUNIT_ASSERT_EQUAL( sal_uInt16(EE_FEATURE_FIELD
), aACPURLFieldInfo2
.pFieldItem
->Which() );
670 SvxURLField
* pACPURLField2
= dynamic_cast<SvxURLField
*> ( const_cast<SvxFieldData
*> (aACPURLFieldInfo2
.pFieldItem
->GetField()) );
671 CPPUNIT_ASSERT(pACPURLField2
);
672 CPPUNIT_ASSERT_EQUAL( aURL2
, pACPURLField2
->GetURL() );
673 CPPUNIT_ASSERT_EQUAL( aRepres2
, pACPURLField2
->GetRepresentation() ) ;
676 EFieldInfo aACPURLFieldInfo3
= aEditEngine
.GetFieldInfo( sal_Int32(0), sal_uInt16(2) );
677 CPPUNIT_ASSERT_EQUAL( sal_Int32(38), aACPURLFieldInfo3
.aPosition
.nIndex
);
678 CPPUNIT_ASSERT_EQUAL( sal_uInt16(EE_FEATURE_FIELD
), aACPURLFieldInfo3
.pFieldItem
->Which() );
679 SvxURLField
* pACPURLField3
= dynamic_cast<SvxURLField
*> ( const_cast<SvxFieldData
*> (aACPURLFieldInfo3
.pFieldItem
->GetField()) );
680 CPPUNIT_ASSERT(pACPURLField3
);
681 CPPUNIT_ASSERT_EQUAL( aURL1
, pACPURLField3
->GetURL() );
682 CPPUNIT_ASSERT_EQUAL( aRepres1
, pACPURLField3
->GetRepresentation() );
685 void Test::testCopyPaste()
687 // Create EditEngine's instance
688 EditEngine
aEditEngine( mpItemPool
.get() );
690 // Get EditDoc for current EditEngine's instance
691 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
693 // Initially no text should be there
694 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
695 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
698 OUString aText
= "This is custom initial text";
699 sal_Int32 aTextLen
= aText
.getLength();
700 aEditEngine
.SetText( aText
);
703 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
704 CPPUNIT_ASSERT_EQUAL( aText
, rDoc
.GetParaAsString(sal_Int32(0)) );
706 // Copy initial text using legacy format
707 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,0,0,aTextLen
) );
709 // Paste text at the end
710 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
713 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aTextLen
, rDoc
.GetTextLen() );
714 CPPUNIT_ASSERT_EQUAL( OUString(aText
+ aText
), rDoc
.GetParaAsString(sal_Int32(0)) );
717 void Test::testMultiParaSelCopyPaste()
719 // Create EditEngine's instance
720 EditEngine
aEditEngine( mpItemPool
.get() );
722 // Get EditDoc for current EditEngine's instance
723 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
725 // Initially no text should be there
726 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
727 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
729 // Insert initial text
730 OUString aFirstPara
= "This is first paragraph";
731 // Selection Ref ........8..............
732 OUString aSecondPara
= "This is second paragraph";
733 // Selection Ref .............14.........
734 OUString aThirdPara
= "This is third paragraph";
735 OUString aText
= aFirstPara
+ "\n" + aSecondPara
+ "\n" + aThirdPara
;
736 sal_Int32 aTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength() + aThirdPara
.getLength();
737 aEditEngine
.SetText( aText
);
738 OUString aCopyText
= "first paragraphThis is second";
739 sal_Int32 aCopyTextLen
= aCopyText
.getLength();
742 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
743 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
744 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
745 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
747 // Copy initial text using legacy format
748 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,8,1,14) );
750 // Paste text at the end
751 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
754 OUString aThirdParaAfterCopyPaste
= aThirdPara
+ "first paragraph";
755 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aCopyTextLen
, rDoc
.GetTextLen() );
756 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
757 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
758 CPPUNIT_ASSERT_EQUAL( aThirdParaAfterCopyPaste
, rDoc
.GetParaAsString(sal_Int32(2)) );
759 CPPUNIT_ASSERT_EQUAL( OUString("This is second"), rDoc
.GetParaAsString(sal_Int32(3)) );
762 void Test::testTabsCopyPaste()
764 // Create EditEngine's instance
765 EditEngine
aEditEngine( mpItemPool
.get() );
767 // Get EditDoc for current EditEngine's instance
768 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
770 // New instance must be empty - no initial text
771 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
772 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
774 // Get corresponding Item for inserting tabs in the text
775 SfxVoidItem
aTab( EE_FEATURE_TAB
);
777 // Insert initial text
778 OUString aParaText
= "sampletextfortestingtab";
779 // Positions Ref ......*6...............*23
780 sal_Int32 aTextLen
= aParaText
.getLength();
781 aEditEngine
.SetText( aParaText
);
784 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
785 CPPUNIT_ASSERT_EQUAL( aParaText
, rDoc
.GetParaAsString(sal_Int32(0)) );
787 // Insert tab 1 at desired position
788 ContentNode
*pNode
= rDoc
.GetObject(0);
789 EditSelection
aSel1( EditPaM(pNode
, 6), EditPaM(pNode
, 6) );
790 aEditEngine
.InsertFeature( aSel1
, aTab
);
793 CPPUNIT_ASSERT_EQUAL( aTextLen
+ 1, rDoc
.GetTextLen() );
794 CPPUNIT_ASSERT_EQUAL( OUString("sample\ttextfortestingtab"), rDoc
.GetParaAsString(sal_Int32(0)) );
796 // Insert tab 2 at desired position
797 EditSelection
aSel2( EditPaM(pNode
, 23+1), EditPaM(pNode
, 23+1) );
798 aEditEngine
.InsertFeature( aSel2
, aTab
);
801 CPPUNIT_ASSERT_EQUAL( aTextLen
+ 2, rDoc
.GetTextLen() );
802 CPPUNIT_ASSERT_EQUAL( OUString("sample\ttextfortestingtab\t"), rDoc
.GetParaAsString(sal_Int32(0)) );
804 // Copy text using legacy format
805 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,6,0,aTextLen
+2) );
807 // Paste text at the end
808 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
811 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aTextLen
- 6 + 4, rDoc
.GetTextLen() );
812 CPPUNIT_ASSERT_EQUAL( OUString("sample\ttextfortestingtab\t\ttextfortestingtab\t"), rDoc
.GetParaAsString(sal_Int32(0)) );
815 class UrlEditEngine
: public EditEngine
818 explicit UrlEditEngine(SfxItemPool
*pPool
) : EditEngine(pPool
) {}
820 virtual OUString
CalcFieldValue( const SvxFieldItem
&, sal_Int32
, sal_Int32
, std::optional
<Color
>&, std::optional
<Color
>&, std::optional
<FontLineStyle
>& ) override
822 return "jim@bob.com"; // a sophisticated view of value:
826 // Odd accounting for hyperlink position & size etc.
827 // https://bugzilla.novell.com/show_bug.cgi?id=467459
828 void Test::testHyperlinkSearch()
830 UrlEditEngine
aEngine(mpItemPool
.get());
831 EditDoc
&rDoc
= aEngine
.GetEditDoc();
833 OUString aSampleText
= "Please write email to . if you find a fish(not a dog).";
834 aEngine
.SetText(aSampleText
);
836 CPPUNIT_ASSERT_EQUAL_MESSAGE("set text", aSampleText
, rDoc
.GetParaAsString(sal_Int32(0)));
838 ContentNode
*pNode
= rDoc
.GetObject(0);
839 EditSelection
aSel(EditPaM(pNode
, 22), EditPaM(pNode
, 22));
840 SvxURLField
aURLField("mailto:///jim@bob.com", "jim@bob.com",
842 SvxFieldItem
aField(aURLField
, EE_FEATURE_FIELD
);
844 aEngine
.InsertField(aSel
, aField
);
846 OUString aContent
= pNode
->GetExpandedText();
847 CPPUNIT_ASSERT_EQUAL_MESSAGE("get text", OUString("Please write email to jim@bob.com. if you find a fish(not a dog)."),
849 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong length", aContent
.getLength(), rDoc
.GetTextLen());
851 // Check expansion and positioning re-work
852 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong length", aContent
.getLength(),
853 pNode
->GetExpandedLen());
854 for (sal_Int32 n
= 0; n
< aContent
.getLength(); n
++)
856 sal_Int32 nStart
= n
, nEnd
= n
;
857 pNode
->UnExpandPositions(nStart
,nEnd
);
858 CPPUNIT_ASSERT_MESSAGE("out of bound start", nStart
< pNode
->Len());
859 CPPUNIT_ASSERT_MESSAGE("out of bound end", nEnd
<= pNode
->Len());
862 static const struct {
863 sal_Int32 mnStart
, mnEnd
;
864 sal_Int32 mnNewStart
, mnNewEnd
;
866 { 0, 1, /* -> */ 0, 1 },
867 { 21, 25, /* -> */ 21, 23 }, // the field is really just one char
868 { 25, 27, /* -> */ 22, 23 },
869 { 50, 56, /* -> */ 40, 46 }
871 for (size_t n
= 0; n
< SAL_N_ELEMENTS(aTrickyOnes
); n
++)
873 sal_Int32 nStart
= aTrickyOnes
[n
].mnStart
;
874 sal_Int32 nEnd
= aTrickyOnes
[n
].mnEnd
;
875 pNode
->UnExpandPositions(nStart
,nEnd
);
877 CPPUNIT_ASSERT_EQUAL_MESSAGE(
878 OString("in row " + OString::number(n
)).getStr(),
879 aTrickyOnes
[n
].mnNewStart
, nStart
);
880 CPPUNIT_ASSERT_EQUAL_MESSAGE(
881 OString("in row " + OString::number(n
)).getStr(),
882 aTrickyOnes
[n
].mnNewEnd
, nEnd
);
885 SvxSearchItem
aItem(1); //SID_SEARCH_ITEM);
886 aItem
.SetBackward(false);
887 aItem
.SetSelection(false);
888 aItem
.SetSearchString("fish");
889 CPPUNIT_ASSERT_MESSAGE("no fish", aEngine
.HasText(aItem
));
890 aItem
.SetSearchString("dog");
891 CPPUNIT_ASSERT_MESSAGE("no dog", aEngine
.HasText(aItem
));
894 bool hasBold(const editeng::Section
& rSecAttr
)
896 return std::any_of(rSecAttr
.maAttributes
.begin(), rSecAttr
.maAttributes
.end(),
897 [](const SfxPoolItem
* p
) {
898 return p
->Which() == EE_CHAR_WEIGHT
899 && static_cast<const SvxWeightItem
*>(p
)->GetWeight() == WEIGHT_BOLD
;
903 bool hasItalic(const editeng::Section
& rSecAttr
)
905 return std::any_of(rSecAttr
.maAttributes
.begin(), rSecAttr
.maAttributes
.end(),
906 [](const SfxPoolItem
* p
) {
907 return p
->Which() == EE_CHAR_ITALIC
908 && static_cast<const SvxPostureItem
*>(p
)->GetPosture() == ITALIC_NORMAL
;
912 void Test::testBoldItalicCopyPaste()
914 // Create EditEngine's instance
915 EditEngine
aEditEngine( mpItemPool
.get() );
917 // Get EditDoc for current EditEngine's instance
918 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
920 // New instance must be empty - no initial text
921 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
922 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
924 // Get corresponding ItemSet for inserting Bold/Italic text
925 std::unique_ptr
<SfxItemSet
> pSet( new SfxItemSet(aEditEngine
.GetEmptyItemSet()) );
926 SvxWeightItem
aBold( WEIGHT_BOLD
, EE_CHAR_WEIGHT
);
927 SvxPostureItem
aItalic( ITALIC_NORMAL
, EE_CHAR_ITALIC
);
929 // Insert initial text
930 OUString aParaText
= "boldeditengineitalic";
931 // Positions Ref ..*2....*8...*13.*17
932 // Bold Ref ..[ BOLD ]......
933 // Italic Ref ........[ ITALIC ]..
934 sal_Int32 aTextLen
= aParaText
.getLength();
935 aEditEngine
.SetText( aParaText
);
937 // Assert changes - text insertion
938 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
939 CPPUNIT_ASSERT_EQUAL( aParaText
, rDoc
.GetParaAsString(sal_Int32(0)) );
941 // Apply Bold to appropriate selection
943 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16
>(1), pSet
->Count() );
944 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(0,2,0,14) );
947 std::unique_ptr
<EditTextObject
> pEditText1( aEditEngine
.CreateTextObject() );
948 std::vector
<editeng::Section
> aAttrs1
;
949 pEditText1
->GetAllSections( aAttrs1
);
950 // There should be 3 sections - woBold - wBold - woBold (w - with, wo - without)
951 CPPUNIT_ASSERT_EQUAL( size_t(3), aAttrs1
.size() );
953 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnParagraph
) );
954 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnStart
) );
955 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs1
[0].mnEnd
) );
956 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].maAttributes
.size()) );
958 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[1].mnParagraph
) );
959 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs1
[1].mnStart
) );
960 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs1
[1].mnEnd
) );
961 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[1].maAttributes
.size()) );
962 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs1
[1]) );
964 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].mnParagraph
) );
965 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs1
[2].mnStart
) );
966 CPPUNIT_ASSERT_EQUAL( 20, static_cast<int>(aAttrs1
[2].mnEnd
) );
967 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].maAttributes
.size()) );
969 // Apply Italic to appropriate selection
970 pSet
.reset( new SfxItemSet(aEditEngine
.GetEmptyItemSet()) );
972 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16
>(1), pSet
->Count() );
973 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(0,8,0,18) );
976 std::unique_ptr
<EditTextObject
> pEditText2( aEditEngine
.CreateTextObject() );
977 std::vector
<editeng::Section
> aAttrs2
;
978 pEditText2
->GetAllSections( aAttrs2
);
979 // There should be 5 sections - woBold&woItalic - wBold&woItalic - wBold&wItalic - woBold&wItalic - woBold&woItalic (w - with, wo - without)
980 CPPUNIT_ASSERT_EQUAL( size_t(5), aAttrs2
.size() );
982 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnParagraph
) );
983 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnStart
) );
984 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[0].mnEnd
) );
985 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].maAttributes
.size()) );
987 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[1].mnParagraph
) );
988 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[1].mnStart
) );
989 CPPUNIT_ASSERT_EQUAL( 8, static_cast<int>(aAttrs2
[1].mnEnd
) );
990 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[1].maAttributes
.size()) );
991 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs2
[1]) );
993 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[2].mnParagraph
) );
994 CPPUNIT_ASSERT_EQUAL( 8, static_cast<int>(aAttrs2
[2].mnStart
) );
995 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs2
[2].mnEnd
) );
996 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[2].maAttributes
.size()) );
997 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs2
[2]) );
998 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs2
[2]) );
1000 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[3].mnParagraph
) );
1001 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs2
[3].mnStart
) );
1002 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[3].mnEnd
) );
1003 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[3].maAttributes
.size()) );
1004 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs2
[3]) );
1006 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[4].mnParagraph
) );
1007 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[4].mnStart
) );
1008 CPPUNIT_ASSERT_EQUAL( 20, static_cast<int>(aAttrs2
[4].mnEnd
) );
1009 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[4].maAttributes
.size()) );
1011 // Copy text using legacy format
1012 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,1,0,aTextLen
-1) );
1014 // Paste text at the end
1015 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
1018 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aTextLen
- 2, rDoc
.GetTextLen() );
1019 CPPUNIT_ASSERT_EQUAL( OUString(aParaText
+ "oldeditengineitali" ), rDoc
.GetParaAsString(sal_Int32(0)) );
1021 // Check updated text for appropriate Bold/Italics
1022 std::unique_ptr
<EditTextObject
> pEditText3( aEditEngine
.CreateTextObject() );
1023 std::vector
<editeng::Section
> aAttrs3
;
1024 pEditText3
->GetAllSections( aAttrs3
);
1025 // There should be 9 sections - woBold&woItalic - wBold&woItalic - wBold&wItalic - woBold&wItalic - woBold&woItalic - wBold&woItalic
1026 // - wBold&wItalic - woBold&wItalic - woBold&woItalic(w - with, wo - without)
1027 CPPUNIT_ASSERT_EQUAL( size_t(9), aAttrs3
.size() );
1029 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].mnParagraph
) );
1030 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].mnStart
) );
1031 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[0].mnEnd
) );
1032 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].maAttributes
.size()) );
1034 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[1].mnParagraph
) );
1035 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[1].mnStart
) );
1036 CPPUNIT_ASSERT_EQUAL( 8, static_cast<int>(aAttrs3
[1].mnEnd
) );
1037 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[1].maAttributes
.size()) );
1038 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[1]) );
1040 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[2].mnParagraph
) );
1041 CPPUNIT_ASSERT_EQUAL( 8, static_cast<int>(aAttrs3
[2].mnStart
) );
1042 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs3
[2].mnEnd
) );
1043 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[2].maAttributes
.size()) );
1044 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[2]) );
1045 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[2]) );
1047 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[3].mnParagraph
) );
1048 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs3
[3].mnStart
) );
1049 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs3
[3].mnEnd
) );
1050 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[3].maAttributes
.size()) );
1051 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[3]) );
1053 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[4].mnParagraph
) );
1054 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs3
[4].mnStart
) );
1055 CPPUNIT_ASSERT_EQUAL( 21, static_cast<int>(aAttrs3
[4].mnEnd
) );
1056 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[4].maAttributes
.size()) );
1058 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[5].mnParagraph
) );
1059 CPPUNIT_ASSERT_EQUAL( 21, static_cast<int>(aAttrs3
[5].mnStart
) );
1060 CPPUNIT_ASSERT_EQUAL( 27, static_cast<int>(aAttrs3
[5].mnEnd
) );
1061 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[5].maAttributes
.size()) );
1062 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[5]) );
1064 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[6].mnParagraph
) );
1065 CPPUNIT_ASSERT_EQUAL( 27, static_cast<int>(aAttrs3
[6].mnStart
) );
1066 CPPUNIT_ASSERT_EQUAL( 33, static_cast<int>(aAttrs3
[6].mnEnd
) );
1067 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[6].maAttributes
.size()) );
1068 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[6]) );
1069 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[6]) );
1071 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[7].mnParagraph
) );
1072 CPPUNIT_ASSERT_EQUAL( 33, static_cast<int>(aAttrs3
[7].mnStart
) );
1073 CPPUNIT_ASSERT_EQUAL( 37, static_cast<int>(aAttrs3
[7].mnEnd
) );
1074 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[7].maAttributes
.size()) );
1075 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[7]) );
1077 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[8].mnParagraph
) );
1078 CPPUNIT_ASSERT_EQUAL( 37, static_cast<int>(aAttrs3
[8].mnStart
) );
1079 CPPUNIT_ASSERT_EQUAL( 38, static_cast<int>(aAttrs3
[8].mnEnd
) );
1080 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[8].maAttributes
.size()) );
1083 // Auxiliary function to test Underline text Copy/Paste using Legacy Format
1084 bool hasUnderline(const editeng::Section
& rSecAttr
)
1086 return std::any_of(rSecAttr
.maAttributes
.begin(), rSecAttr
.maAttributes
.end(),
1087 [](const SfxPoolItem
* p
) {
1088 return p
->Which() == EE_CHAR_UNDERLINE
1089 && static_cast<const SvxUnderlineItem
*>(p
)->GetLineStyle() == LINESTYLE_SINGLE
;
1093 void Test::testUnderlineCopyPaste()
1095 // Create EditEngine's instance
1096 EditEngine
aEditEngine( mpItemPool
.get() );
1098 // Get EditDoc for current EditEngine's instance
1099 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
1101 // New instance must be empty - no initial text
1102 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
1103 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
1105 // Get corresponding ItemSet for inserting Underline text
1106 std::unique_ptr
<SfxItemSet
> pSet( new SfxItemSet(aEditEngine
.GetEmptyItemSet()) );
1107 SvxUnderlineItem
aULine( LINESTYLE_SINGLE
, EE_CHAR_UNDERLINE
);
1109 // Insert initial text
1110 OUString aParaText
= "sampletextforunderline";
1111 // Positions Ref ......*6.........*17..
1112 // Underline Ref ......[UNDERLINE ]....
1113 sal_Int32 aTextLen
= aParaText
.getLength();
1114 aEditEngine
.SetText( aParaText
);
1116 // Apply Underline style
1117 pSet
->Put( aULine
);
1118 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16
>(1), pSet
->Count() );
1119 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(0,6,0,18) );
1122 std::unique_ptr
<EditTextObject
> pEditText1( aEditEngine
.CreateTextObject() );
1123 std::vector
<editeng::Section
> aAttrs1
;
1124 pEditText1
->GetAllSections( aAttrs1
);
1126 // There should be 3 sections - woUnderline - wUnderline - woUnderline (w - with, wo - without)
1127 CPPUNIT_ASSERT_EQUAL( size_t(3), aAttrs1
.size() );
1129 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnParagraph
) );
1130 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnStart
) );
1131 CPPUNIT_ASSERT_EQUAL( 6, static_cast<int>(aAttrs1
[0].mnEnd
) );
1132 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].maAttributes
.size()) );
1134 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[1].mnParagraph
) );
1135 CPPUNIT_ASSERT_EQUAL( 6, static_cast<int>(aAttrs1
[1].mnStart
) );
1136 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs1
[1].mnEnd
) );
1137 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[1].maAttributes
.size()) );
1138 CPPUNIT_ASSERT_MESSAGE( "This section must be underlined.", hasUnderline(aAttrs1
[1]) );
1140 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].mnParagraph
) );
1141 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs1
[2].mnStart
) );
1142 CPPUNIT_ASSERT_EQUAL( 22, static_cast<int>(aAttrs1
[2].mnEnd
) );
1143 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].maAttributes
.size()) );
1145 // Copy text using legacy format
1146 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,6,0,aTextLen
-4) );
1148 // Paste text at the end
1149 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
1152 CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32
>(aTextLen
+ strlen("textforunder")), rDoc
.GetTextLen() );
1153 CPPUNIT_ASSERT_EQUAL( OUString(aParaText
+ "textforunder" ), rDoc
.GetParaAsString(sal_Int32(0)) );
1155 // Check updated text for appropriate Underline
1156 std::unique_ptr
<EditTextObject
> pEditText2( aEditEngine
.CreateTextObject() );
1157 std::vector
<editeng::Section
> aAttrs2
;
1158 pEditText2
->GetAllSections( aAttrs2
);
1160 // There should be 4 sections - woUnderline - wUnderline - woUnderline - wUnderline (w - with, wo - without)
1161 CPPUNIT_ASSERT_EQUAL( size_t(4), aAttrs2
.size() );
1163 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnParagraph
) );
1164 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnStart
) );
1165 CPPUNIT_ASSERT_EQUAL( 6, static_cast<int>(aAttrs2
[0].mnEnd
) );
1166 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].maAttributes
.size()) );
1168 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[1].mnParagraph
) );
1169 CPPUNIT_ASSERT_EQUAL( 6, static_cast<int>(aAttrs2
[1].mnStart
) );
1170 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[1].mnEnd
) );
1171 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[1].maAttributes
.size()) );
1172 CPPUNIT_ASSERT_MESSAGE( "This section must be underlined.", hasUnderline(aAttrs2
[1]) );
1174 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[2].mnParagraph
) );
1175 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[2].mnStart
) );
1176 CPPUNIT_ASSERT_EQUAL( 22, static_cast<int>(aAttrs2
[2].mnEnd
) );
1177 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[2].maAttributes
.size()) );
1179 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[3].mnParagraph
) );
1180 CPPUNIT_ASSERT_EQUAL( 22, static_cast<int>(aAttrs2
[3].mnStart
) );
1181 CPPUNIT_ASSERT_EQUAL( 34, static_cast<int>(aAttrs2
[3].mnEnd
) );
1182 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[3].maAttributes
.size()) );
1183 CPPUNIT_ASSERT_MESSAGE( "This section must be underlined.", hasUnderline(aAttrs2
[3]) );
1186 void Test::testMultiParaCopyPaste()
1188 // Create EditEngine's instance
1189 EditEngine
aEditEngine( mpItemPool
.get() );
1191 // Get EditDoc for current EditEngine's instance
1192 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
1194 // Initially no text should be there
1195 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
1196 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
1198 // Insert initial text
1199 OUString aFirstPara
= "This is first paragraph";
1200 OUString aSecondPara
= "This is second paragraph";
1201 OUString aThirdPara
= "This is third paragraph";
1202 OUString aText
= aFirstPara
+ "\n" + aSecondPara
+ "\n" + aThirdPara
;
1203 sal_Int32 aTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength() + aThirdPara
.getLength();
1204 aEditEngine
.SetText( aText
);
1205 sal_Int32 aCopyTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength();
1208 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
1209 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1210 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1211 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1213 // Copy initial text using legacy format
1214 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,0,1,aSecondPara
.getLength()) );
1216 // Paste text at the end
1217 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
1220 OUString aThirdParaAfterCopyPaste
= aThirdPara
+ aFirstPara
;
1221 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aCopyTextLen
, rDoc
.GetTextLen() );
1222 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1223 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1224 CPPUNIT_ASSERT_EQUAL( aThirdParaAfterCopyPaste
, rDoc
.GetParaAsString(sal_Int32(2)) );
1225 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(3)) );
1228 void Test::testParaBoldItalicCopyPaste()
1230 // Create EditEngine's instance
1231 EditEngine
aEditEngine( mpItemPool
.get() );
1233 // Get EditDoc for current EditEngine's instance
1234 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
1236 // Initially no text should be there
1237 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
1238 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
1240 // Get corresponding ItemSet for inserting Bold/Italic text
1241 std::unique_ptr
<SfxItemSet
> pSet( new SfxItemSet(aEditEngine
.GetEmptyItemSet()) );
1242 SvxWeightItem
aBold( WEIGHT_BOLD
, EE_CHAR_WEIGHT
);
1243 SvxPostureItem
aItalic( ITALIC_NORMAL
, EE_CHAR_ITALIC
);
1245 // Insert initial text
1246 OUString aFirstPara
= "This is first paragraph";
1247 // Positions Ref .....*5.*8....*14*17...
1248 // Bold Ref .....[ BOLD ].....
1249 // Italic Ref ..............[ ITA
1250 // Copy Ref ........[ Copy Sel
1251 OUString aSecondPara
= "This is second paragraph";
1252 // Positions Ref .....*5.*8...*13..*18...
1253 // Bold Ref .....[ BOLD ].....
1254 // Italic Ref LIC ]...............
1255 // Copy Ref ection ]..........
1256 OUString aThirdPara
= "This is third paragraph";
1257 OUString aText
= aFirstPara
+ "\n" + aSecondPara
+ "\n" + aThirdPara
;
1258 sal_Int32 aTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength() + aThirdPara
.getLength();
1259 aEditEngine
.SetText( aText
);
1260 OUString aCopyText
= "first paragraphThis is second";
1261 sal_Int32 aCopyTextLen
= aCopyText
.getLength();
1263 // Assert changes - text insertion
1264 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
1265 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1266 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1267 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1269 // Apply Bold to appropriate selections
1271 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16
>(1), pSet
->Count() );
1272 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(0,5,0,18) );
1273 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(1,5,1,19) );
1276 std::unique_ptr
<EditTextObject
> pEditText1( aEditEngine
.CreateTextObject() );
1277 std::vector
<editeng::Section
> aAttrs1
;
1278 pEditText1
->GetAllSections( aAttrs1
);
1279 // There should be 7 sections - woB - wB - woB -woB -wB -woB -woB (w - with, wo - without, B - Bold, I - Italic)
1280 CPPUNIT_ASSERT_EQUAL( size_t(7), aAttrs1
.size() );
1282 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnParagraph
) );
1283 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].mnStart
) );
1284 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs1
[0].mnEnd
) );
1285 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[0].maAttributes
.size()) );
1287 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[1].mnParagraph
) );
1288 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs1
[1].mnStart
) );
1289 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs1
[1].mnEnd
) );
1290 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[1].maAttributes
.size()) );
1291 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs1
[1]) );
1293 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].mnParagraph
) );
1294 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs1
[2].mnStart
) );
1295 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs1
[2].mnEnd
) );
1296 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[2].maAttributes
.size()) );
1298 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[3].mnParagraph
) );
1299 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[3].mnStart
) );
1300 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs1
[3].mnEnd
) );
1301 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[3].maAttributes
.size()) );
1303 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[4].mnParagraph
) );
1304 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs1
[4].mnStart
) );
1305 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs1
[4].mnEnd
) );
1306 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[4].maAttributes
.size()) );
1307 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs1
[4]) );
1309 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs1
[5].mnParagraph
) );
1310 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs1
[5].mnStart
) );
1311 CPPUNIT_ASSERT_EQUAL( 24, static_cast<int>(aAttrs1
[5].mnEnd
) );
1312 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[5].maAttributes
.size()) );
1314 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs1
[6].mnParagraph
) );
1315 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[6].mnStart
) );
1316 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs1
[6].mnEnd
) );
1317 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs1
[6].maAttributes
.size()) );
1319 // Apply Italic to appropriate selection
1320 pSet
.reset( new SfxItemSet(aEditEngine
.GetEmptyItemSet()) );
1322 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16
>(1), pSet
->Count() );
1323 aEditEngine
.QuickSetAttribs( *pSet
, ESelection(0,14,1,9) );
1326 std::unique_ptr
<EditTextObject
> pEditText2( aEditEngine
.CreateTextObject() );
1327 std::vector
<editeng::Section
> aAttrs2
;
1328 pEditText2
->GetAllSections( aAttrs2
);
1329 // 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)
1330 CPPUNIT_ASSERT_EQUAL( size_t(9), aAttrs2
.size() );
1332 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnParagraph
) );
1333 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].mnStart
) );
1334 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs2
[0].mnEnd
) );
1335 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[0].maAttributes
.size()) );
1337 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[1].mnParagraph
) );
1338 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs2
[1].mnStart
) );
1339 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs2
[1].mnEnd
) );
1340 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[1].maAttributes
.size()) );
1341 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs2
[1]) );
1343 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[2].mnParagraph
) );
1344 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs2
[2].mnStart
) );
1345 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[2].mnEnd
) );
1346 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[2].maAttributes
.size()) );
1347 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs2
[2]) );
1348 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs2
[2]) );
1350 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[3].mnParagraph
) );
1351 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs2
[3].mnStart
) );
1352 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs2
[3].mnEnd
) );
1353 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[3].maAttributes
.size()) );
1354 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs2
[3]) );
1356 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[4].mnParagraph
) );
1357 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[4].mnStart
) );
1358 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs2
[4].mnEnd
) );
1359 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[4].maAttributes
.size()) );
1360 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs2
[4]) );
1362 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[5].mnParagraph
) );
1363 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs2
[5].mnStart
) );
1364 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs2
[5].mnEnd
) );
1365 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[5].maAttributes
.size()) );
1366 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs2
[5]) );
1367 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs2
[5]) );
1369 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[6].mnParagraph
) );
1370 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs2
[6].mnStart
) );
1371 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs2
[6].mnEnd
) );
1372 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[6].maAttributes
.size()) );
1373 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs2
[6]) );
1375 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs2
[7].mnParagraph
) );
1376 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs2
[7].mnStart
) );
1377 CPPUNIT_ASSERT_EQUAL( 24, static_cast<int>(aAttrs2
[7].mnEnd
) );
1378 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[7].maAttributes
.size()) );
1380 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs2
[8].mnParagraph
) );
1381 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[8].mnStart
) );
1382 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs2
[8].mnEnd
) );
1383 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs2
[8].maAttributes
.size()) );
1385 // Copy text using legacy format
1386 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,8,1,14) );
1388 // Paste text at the end
1389 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetEndPaM(), true );
1392 OUString aThirdParaAfterCopyPaste
= aThirdPara
+ "first paragraph";
1393 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aCopyTextLen
, rDoc
.GetTextLen() );
1394 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1395 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1396 CPPUNIT_ASSERT_EQUAL( aThirdParaAfterCopyPaste
, rDoc
.GetParaAsString(sal_Int32(2)) );
1397 CPPUNIT_ASSERT_EQUAL( OUString("This is second"), rDoc
.GetParaAsString(sal_Int32(3)) );
1399 // Check updated text for appropriate Bold/Italics
1400 std::unique_ptr
<EditTextObject
> pEditText3( aEditEngine
.CreateTextObject() );
1401 std::vector
<editeng::Section
> aAttrs3
;
1402 pEditText3
->GetAllSections( aAttrs3
);
1403 // There should be 15 sections - woB&woI - wB&woI - wB&wI -woB&wI - woB&wI - wB&wI - wB&woI - woB&woI - woB&woI
1404 // - wB&woI - wB&wI - woB&wI - -woB&wI - wB&wI - wB&woI (w - with, wo - without, B - Bold, I - Italic)
1405 CPPUNIT_ASSERT_EQUAL( size_t(15), aAttrs3
.size() );
1407 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].mnParagraph
) );
1408 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].mnStart
) );
1409 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[0].mnEnd
) );
1410 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[0].maAttributes
.size()) );
1412 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[1].mnParagraph
) );
1413 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[1].mnStart
) );
1414 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs3
[1].mnEnd
) );
1415 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[1].maAttributes
.size()) );
1416 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[1]) );
1418 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[2].mnParagraph
) );
1419 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs3
[2].mnStart
) );
1420 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs3
[2].mnEnd
) );
1421 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[2].maAttributes
.size()) );
1422 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[2]) );
1423 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[2]) );
1425 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[3].mnParagraph
) );
1426 CPPUNIT_ASSERT_EQUAL( 18, static_cast<int>(aAttrs3
[3].mnStart
) );
1427 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs3
[3].mnEnd
) );
1428 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[3].maAttributes
.size()) );
1429 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[3]) );
1431 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[4].mnParagraph
) );
1432 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[4].mnStart
) );
1433 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[4].mnEnd
) );
1434 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[4].maAttributes
.size()) );
1435 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[4]) );
1437 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[5].mnParagraph
) );
1438 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[5].mnStart
) );
1439 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs3
[5].mnEnd
) );
1440 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[5].maAttributes
.size()) );
1441 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[5]) );
1442 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[5]) );
1444 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[6].mnParagraph
) );
1445 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs3
[6].mnStart
) );
1446 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs3
[6].mnEnd
) );
1447 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[6].maAttributes
.size()) );
1448 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[6]) );
1450 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[7].mnParagraph
) );
1451 CPPUNIT_ASSERT_EQUAL( 19, static_cast<int>(aAttrs3
[7].mnStart
) );
1452 CPPUNIT_ASSERT_EQUAL( 24, static_cast<int>(aAttrs3
[7].mnEnd
) );
1453 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[7].maAttributes
.size()) );
1455 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[8].mnParagraph
) );
1456 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[8].mnStart
) );
1457 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs3
[8].mnEnd
) );
1458 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[8].maAttributes
.size()) );
1460 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[9].mnParagraph
) );
1461 CPPUNIT_ASSERT_EQUAL( 23, static_cast<int>(aAttrs3
[9].mnStart
) );
1462 CPPUNIT_ASSERT_EQUAL( 29, static_cast<int>(aAttrs3
[9].mnEnd
) );
1463 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[9].maAttributes
.size()) );
1464 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[9]) );
1466 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[10].mnParagraph
) );
1467 CPPUNIT_ASSERT_EQUAL( 29, static_cast<int>(aAttrs3
[10].mnStart
) );
1468 CPPUNIT_ASSERT_EQUAL( 33, static_cast<int>(aAttrs3
[10].mnEnd
) );
1469 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[10].maAttributes
.size()) );
1470 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[10]) );
1471 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[10]) );
1473 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[11].mnParagraph
) );
1474 CPPUNIT_ASSERT_EQUAL( 33, static_cast<int>(aAttrs3
[11].mnStart
) );
1475 CPPUNIT_ASSERT_EQUAL( 38, static_cast<int>(aAttrs3
[11].mnEnd
) );
1476 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[11].maAttributes
.size()) );
1477 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[11]) );
1479 CPPUNIT_ASSERT_EQUAL( 3, static_cast<int>(aAttrs3
[12].mnParagraph
) );
1480 CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(aAttrs3
[12].mnStart
) );
1481 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[12].mnEnd
) );
1482 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[12].maAttributes
.size()) );
1483 CPPUNIT_ASSERT_MESSAGE( "This section must be italic.", hasItalic(aAttrs3
[12]) );
1485 CPPUNIT_ASSERT_EQUAL( 3, static_cast<int>(aAttrs3
[13].mnParagraph
) );
1486 CPPUNIT_ASSERT_EQUAL( 5, static_cast<int>(aAttrs3
[13].mnStart
) );
1487 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs3
[13].mnEnd
) );
1488 CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(aAttrs3
[13].maAttributes
.size()) );
1489 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasBold(aAttrs3
[13]) );
1490 CPPUNIT_ASSERT_MESSAGE( "This section must be bold and italic.", hasItalic(aAttrs3
[13]) );
1492 CPPUNIT_ASSERT_EQUAL( 3, static_cast<int>(aAttrs3
[14].mnParagraph
) );
1493 CPPUNIT_ASSERT_EQUAL( 9, static_cast<int>(aAttrs3
[14].mnStart
) );
1494 CPPUNIT_ASSERT_EQUAL( 14, static_cast<int>(aAttrs3
[14].mnEnd
) );
1495 CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(aAttrs3
[14].maAttributes
.size()) );
1496 CPPUNIT_ASSERT_MESSAGE( "This section must be bold.", hasBold(aAttrs3
[14]) );
1499 void Test::testParaStartCopyPaste()
1501 // Create EditEngine's instance
1502 EditEngine
aEditEngine( mpItemPool
.get() );
1504 // Get EditDoc for current EditEngine's instance
1505 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
1507 // Initially no text should be there
1508 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
1509 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
1511 // Insert initial text
1512 OUString aFirstPara
= "This is first paragraph";
1513 // Selection Ref ........8..............
1514 OUString aSecondPara
= "This is second paragraph";
1515 // Selection Ref .............14.........
1516 OUString aThirdPara
= "This is third paragraph";
1517 OUString aText
= aFirstPara
+ "\n" + aSecondPara
+ "\n" + aThirdPara
;
1518 sal_Int32 aTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength() + aThirdPara
.getLength();
1519 aEditEngine
.SetText( aText
);
1520 OUString aCopyText
= "first paragraphThis is second";
1521 sal_Int32 aCopyTextLen
= aCopyText
.getLength();
1524 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
1525 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1526 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1527 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1529 // Copy initial text using legacy format
1530 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(0,8,1,14) );
1532 // Paste text at the start
1533 aEditEngine
.InsertText( xData
, OUString(), rDoc
.GetStartPaM(), true );
1536 OUString aSecondParaAfterCopyPaste
= "This is second" + aFirstPara
;
1537 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aCopyTextLen
, rDoc
.GetTextLen() );
1538 CPPUNIT_ASSERT_EQUAL( OUString("first paragraph"), rDoc
.GetParaAsString(sal_Int32(0)) );
1539 CPPUNIT_ASSERT_EQUAL( aSecondParaAfterCopyPaste
, rDoc
.GetParaAsString(sal_Int32(1)) );
1540 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1541 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(3)) );
1544 void Test::testSectionAttributes()
1546 EditEngine
aEngine(mpItemPool
.get());
1548 std::unique_ptr
<SfxItemSet
> pSet(new SfxItemSet(aEngine
.GetEmptyItemSet()));
1549 SvxWeightItem
aBold(WEIGHT_BOLD
, EE_CHAR_WEIGHT
);
1550 SvxPostureItem
aItalic(ITALIC_NORMAL
, EE_CHAR_ITALIC
);
1553 aEngine
.SetText("aaabbbccc");
1555 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be exactly one item.", static_cast<sal_uInt16
>(1), pSet
->Count());
1556 aEngine
.QuickSetAttribs(*pSet
, ESelection(0,0,0,6)); // 'aaabbb' - end point is not inclusive.
1557 pSet
.reset(new SfxItemSet(aEngine
.GetEmptyItemSet()));
1559 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be exactly one item.", static_cast<sal_uInt16
>(1), pSet
->Count());
1561 aEngine
.QuickSetAttribs(*pSet
, ESelection(0,3,0,9)); // 'bbbccc'
1562 std::unique_ptr
<EditTextObject
> pEditText(aEngine
.CreateTextObject());
1563 CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText
);
1564 std::vector
<editeng::Section
> aAttrs
;
1565 pEditText
->GetAllSections(aAttrs
);
1567 // Now, we should have a total of 3 sections.
1568 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be 3 sections.", static_cast<size_t>(3), aAttrs
.size());
1570 // First section should be 0-3 of paragraph 0, and it should only have boldness applied.
1571 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnParagraph
));
1572 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnStart
));
1573 CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(aAttrs
[0].mnEnd
));
1574 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[0].maAttributes
.size()));
1575 CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(aAttrs
[0]));
1577 // Second section should be 3-6, and it should be both bold and italic.
1578 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[1].mnParagraph
));
1579 CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(aAttrs
[1].mnStart
));
1580 CPPUNIT_ASSERT_EQUAL(6, static_cast<int>(aAttrs
[1].mnEnd
));
1581 CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(aAttrs
[1].maAttributes
.size()));
1582 CPPUNIT_ASSERT_MESSAGE("This section must be bold and italic.", hasBold(aAttrs
[1]));
1583 CPPUNIT_ASSERT_MESSAGE("This section must be bold and italic.", hasItalic(aAttrs
[1]));
1585 // Third section should be 6-9, and it should be only italic.
1586 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[2].mnParagraph
));
1587 CPPUNIT_ASSERT_EQUAL(6, static_cast<int>(aAttrs
[2].mnStart
));
1588 CPPUNIT_ASSERT_EQUAL(9, static_cast<int>(aAttrs
[2].mnEnd
));
1589 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[2].maAttributes
.size()));
1590 CPPUNIT_ASSERT_MESSAGE("This section must be italic.", hasItalic(aAttrs
[2]));
1594 // Set text consisting of 5 paragraphs with the 2nd and 4th paragraphs
1597 aEngine
.SetText("one\n\ntwo\n\nthree");
1598 sal_Int32 nParaCount
= aEngine
.GetParagraphCount();
1599 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), nParaCount
);
1601 // Apply boldness to paragraphs 1, 3, 5 only. Leave 2 and 4 unformatted.
1602 pSet
.reset(new SfxItemSet(aEngine
.GetEmptyItemSet()));
1604 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be exactly one item.", static_cast<sal_uInt16
>(1), pSet
->Count());
1605 aEngine
.QuickSetAttribs(*pSet
, ESelection(0,0,0,3));
1606 aEngine
.QuickSetAttribs(*pSet
, ESelection(2,0,2,3));
1607 aEngine
.QuickSetAttribs(*pSet
, ESelection(4,0,4,5));
1609 std::unique_ptr
<EditTextObject
> pEditText(aEngine
.CreateTextObject());
1610 CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText
);
1611 std::vector
<editeng::Section
> aAttrs
;
1612 pEditText
->GetAllSections(aAttrs
);
1613 CPPUNIT_ASSERT_EQUAL(size_t(5), aAttrs
.size());
1615 // 1st, 3rd and 5th sections should correspond with 1st, 3rd and 5th paragraphs.
1616 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnParagraph
));
1617 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnStart
));
1618 CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(aAttrs
[0].mnEnd
));
1619 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[0].maAttributes
.size()));
1620 CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(aAttrs
[0]));
1622 CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(aAttrs
[2].mnParagraph
));
1623 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[2].mnStart
));
1624 CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(aAttrs
[2].mnEnd
));
1625 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[2].maAttributes
.size()));
1626 CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(aAttrs
[2]));
1628 CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(aAttrs
[4].mnParagraph
));
1629 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[4].mnStart
));
1630 CPPUNIT_ASSERT_EQUAL(5, static_cast<int>(aAttrs
[4].mnEnd
));
1631 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[4].maAttributes
.size()));
1632 CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(aAttrs
[4]));
1634 // The 2nd and 4th paragraphs should be empty.
1635 CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aAttrs
[1].mnParagraph
));
1636 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[1].mnStart
));
1637 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[1].mnEnd
));
1638 CPPUNIT_ASSERT_MESSAGE("Attribute array should be empty.", aAttrs
[1].maAttributes
.empty());
1640 CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(aAttrs
[3].mnParagraph
));
1641 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[3].mnStart
));
1642 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[3].mnEnd
));
1643 CPPUNIT_ASSERT_MESSAGE("Attribute array should be empty.", aAttrs
[3].maAttributes
.empty());
1649 aEngine
.SetText("one\ntwo");
1650 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(2), aEngine
.GetParagraphCount());
1652 // embolden 2nd paragraph
1653 pSet
.reset(new SfxItemSet(aEngine
.GetEmptyItemSet()));
1655 aEngine
.QuickSetAttribs(*pSet
, ESelection(1,0,1,3));
1656 // disboldify 1st paragraph
1657 SvxWeightItem
aNotSoBold(WEIGHT_NORMAL
, EE_CHAR_WEIGHT
);
1658 pSet
->Put(aNotSoBold
);
1659 aEngine
.QuickSetAttribs(*pSet
, ESelection(0,0,0,3));
1661 // now delete & join the paragraphs - this is fdo#85496 scenario
1662 aEngine
.QuickDelete(ESelection(0,0,1,3));
1663 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), aEngine
.GetParagraphCount());
1665 std::unique_ptr
<EditTextObject
> pEditText(aEngine
.CreateTextObject());
1666 CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText
);
1667 std::vector
<editeng::Section
> aAttrs
;
1668 pEditText
->GetAllSections(aAttrs
);
1670 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aAttrs
.size());
1672 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnParagraph
));
1673 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnStart
));
1674 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(aAttrs
[0].mnEnd
));
1675 std::set
<sal_uInt16
> whiches
;
1676 for (size_t i
= 0; i
< aAttrs
[0].maAttributes
.size(); ++i
)
1678 sal_uInt16
const nWhich(aAttrs
[0].maAttributes
[i
]->Which());
1679 CPPUNIT_ASSERT_MESSAGE("duplicate item in text portion attributes",
1680 whiches
.insert(nWhich
).second
);
1685 void Test::testLargeParaCopyPaste()
1687 // Create EditEngine's instance
1688 EditEngine
aEditEngine( mpItemPool
.get() );
1690 // Get EditDoc for current EditEngine's instance
1691 EditDoc
&rDoc
= aEditEngine
.GetEditDoc();
1693 // Initially no text should be there
1694 CPPUNIT_ASSERT_EQUAL( sal_Int32(0), rDoc
.GetTextLen() );
1695 CPPUNIT_ASSERT_EQUAL( OUString(), rDoc
.GetParaAsString(sal_Int32(0)) );
1697 // Insert initial text
1698 OUString aFirstPara
= "This is first paragraph";
1699 OUString aSecondPara
= "This is second paragraph";
1700 OUString aThirdPara
= "This is third paragraph";
1701 OUString aFourthPara
= "This is fourth paragraph";
1702 OUString aFifthPara
= "This is fifth paragraph";
1703 OUString aSixthPara
= "This is sixth paragraph";
1704 //Positions Ref: ........*8.............
1705 OUString aSeventhPara
= "This is seventh paragraph";
1706 OUString aEighthPara
= "This is eighth paragraph";
1707 //Positions Ref: .............*13
1708 OUString aNinthPara
= "This is ninth paragraph";
1709 OUString aTenthPara
= "This is tenth paragraph";
1710 OUString aText
= aFirstPara
+ "\n" + aSecondPara
+ "\n" + aThirdPara
+ "\n" +
1711 aFourthPara
+ "\n" + aFifthPara
+ "\n" + aSixthPara
+ "\n" + aSeventhPara
+ "\n" +
1712 aEighthPara
+ "\n" + aNinthPara
+ "\n" + aTenthPara
;
1713 sal_Int32 aTextLen
= aFirstPara
.getLength() + aSecondPara
.getLength() + aThirdPara
.getLength() +
1714 aFourthPara
.getLength() + aFifthPara
.getLength() + aSixthPara
.getLength() +
1715 aSeventhPara
.getLength() + aEighthPara
.getLength() + aNinthPara
.getLength() + aTenthPara
.getLength();
1716 aEditEngine
.SetText( aText
);
1717 OUString aCopyText
= "sixth paragraphThis is seventh paragraphThis is eighth";
1718 sal_Int32 aCopyTextLen
= aCopyText
.getLength();
1721 CPPUNIT_ASSERT_EQUAL( aTextLen
, rDoc
.GetTextLen() );
1722 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1723 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1724 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1725 CPPUNIT_ASSERT_EQUAL( aFourthPara
, rDoc
.GetParaAsString(sal_Int32(3)) );
1726 CPPUNIT_ASSERT_EQUAL( aFifthPara
, rDoc
.GetParaAsString(sal_Int32(4)) );
1727 CPPUNIT_ASSERT_EQUAL( aSixthPara
, rDoc
.GetParaAsString(sal_Int32(5)) );
1728 CPPUNIT_ASSERT_EQUAL( aSeventhPara
, rDoc
.GetParaAsString(sal_Int32(6)) );
1729 CPPUNIT_ASSERT_EQUAL( aEighthPara
, rDoc
.GetParaAsString(sal_Int32(7)) );
1730 CPPUNIT_ASSERT_EQUAL( aNinthPara
, rDoc
.GetParaAsString(sal_Int32(8)) );
1731 CPPUNIT_ASSERT_EQUAL( aTenthPara
, rDoc
.GetParaAsString(sal_Int32(9)) );
1733 // Copy initial text using legacy format
1734 uno::Reference
< datatransfer::XTransferable
> xData
= aEditEngine
.CreateTransferable( ESelection(5,8,7,14) );
1736 // Paste text at the end of 4th Para
1737 ContentNode
* pLastNode
= rDoc
.GetObject(3);
1738 aEditEngine
.InsertText( xData
, OUString(), EditPaM( pLastNode
, pLastNode
->Len() ), true );
1741 OUString aFourthParaAfterCopyPaste
= aFourthPara
+ "sixth paragraph";
1742 CPPUNIT_ASSERT_EQUAL( aTextLen
+ aCopyTextLen
, rDoc
.GetTextLen() );
1743 CPPUNIT_ASSERT_EQUAL( aFirstPara
, rDoc
.GetParaAsString(sal_Int32(0)) );
1744 CPPUNIT_ASSERT_EQUAL( aSecondPara
, rDoc
.GetParaAsString(sal_Int32(1)) );
1745 CPPUNIT_ASSERT_EQUAL( aThirdPara
, rDoc
.GetParaAsString(sal_Int32(2)) );
1746 CPPUNIT_ASSERT_EQUAL( aFourthParaAfterCopyPaste
, rDoc
.GetParaAsString(sal_Int32(3)) );
1747 CPPUNIT_ASSERT_EQUAL( aSeventhPara
, rDoc
.GetParaAsString(sal_Int32(4)) );
1748 CPPUNIT_ASSERT_EQUAL( OUString("This is eighth"), rDoc
.GetParaAsString(sal_Int32(5)) );
1749 CPPUNIT_ASSERT_EQUAL( aFifthPara
, rDoc
.GetParaAsString(sal_Int32(6)) );
1750 CPPUNIT_ASSERT_EQUAL( aSixthPara
, rDoc
.GetParaAsString(sal_Int32(7)) );
1751 CPPUNIT_ASSERT_EQUAL( aSeventhPara
, rDoc
.GetParaAsString(sal_Int32(8)) );
1752 CPPUNIT_ASSERT_EQUAL( aEighthPara
, rDoc
.GetParaAsString(sal_Int32(9)) );
1753 CPPUNIT_ASSERT_EQUAL( aNinthPara
, rDoc
.GetParaAsString(sal_Int32(10)) );
1754 CPPUNIT_ASSERT_EQUAL( aTenthPara
, rDoc
.GetParaAsString(sal_Int32(11)) );
1757 OUString
lcl_translitTest(EditEngine
& aEditEngine
, const OUString
& text
, const ESelection
& esel
, const TransliterationFlags nType
)
1759 aEditEngine
.SetText(text
);
1760 aEditEngine
.TransliterateText(esel
, nType
);
1761 return aEditEngine
.GetText();
1765 void Test::testTransliterate()
1767 // Create EditEngine's instance
1768 EditEngine
editEng( mpItemPool
.get() );
1770 OUString
sText("one (two) three");
1771 editEng
.SetText(sText
);
1772 editEng
.TransliterateText(ESelection(0, 0, 0, sText
.getLength()), TransliterationFlags::TITLE_CASE
);
1773 CPPUNIT_ASSERT_EQUAL(OUString("One (Two) Three"), editEng
.GetText());
1775 using TF
= TransliterationFlags
;
1776 const OUString sText2
= "Mary Jones met joe Smith. Time Passed.";
1779 ESelection
esel(0, selStart
, 0, selEnd
);
1781 /* DocumentContentOperationsManager checks if the cursor is inside of a word before transliterating,
1782 * but Edit Engine has no such check. Therefore, behavior is different between these two when the
1783 * cursor is on a word boundary. */
1785 /* No selection tests. Cursor between the ' ' and 'm' before 'met'. */
1786 CPPUNIT_ASSERT_EQUAL(OUString(""), editEng
.GetText(esel
));
1787 CPPUNIT_ASSERT_EQUAL(OUString("Mary jones met joe smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1788 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1789 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MET joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1790 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1792 /* No selection tests. Cursor between the 't' and the ' ' after 'met'. */
1795 esel
= ESelection(0, selStart
, 0, selEnd
);
1796 CPPUNIT_ASSERT_EQUAL(OUString(""), editEng
.GetText(esel
));
1797 CPPUNIT_ASSERT_EQUAL(OUString("Mary jones met joe smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1798 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1799 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1800 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1802 /* No selection tests. Cursor between the 'h' and the '.' after 'Smith'. */
1805 esel
= ESelection(0, selStart
, 0, selEnd
);
1806 CPPUNIT_ASSERT_EQUAL(OUString(""), editEng
.GetText(esel
));
1807 CPPUNIT_ASSERT_EQUAL(OUString("Mary jones met joe smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1808 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1809 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1810 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1812 /* No selection tests. Cursor between the 'm' and 'e' in 'met'. */
1815 esel
= ESelection(0, selStart
, 0, selEnd
);
1816 CPPUNIT_ASSERT_EQUAL(OUString(""), editEng
.GetText(esel
));
1817 CPPUNIT_ASSERT_EQUAL(OUString("Mary jones met joe smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1818 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1819 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MET joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1820 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1822 /* Test behavior when there is a selection that does not cross a word boundary: "met" */
1825 esel
= ESelection(0, selStart
, 0, selEnd
);
1826 CPPUNIT_ASSERT_EQUAL(OUString("met"), editEng
.GetText(esel
));
1827 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1828 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1829 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MET joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1830 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1832 /* Test behavior when there is a selection that does not begin at a word boundary: "et" */
1835 esel
= ESelection(0, selStart
, 0, selEnd
);
1836 CPPUNIT_ASSERT_EQUAL(OUString("et"), editEng
.GetText(esel
));
1837 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mEt joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1838 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mEt joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1839 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mET joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1840 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1842 /* Test behavior when there is a selection that ends in the middle of a word */
1845 esel
= ESelection(0, selStart
, 0, selEnd
);
1846 CPPUNIT_ASSERT_EQUAL(OUString("me"), editEng
.GetText(esel
));
1847 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1848 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1849 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MEt joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1850 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1853 /* Test behavior when there is a selection that crosses a word boundary: "nes met joe Sm" */
1856 esel
= ESelection(0, selStart
, 0, selEnd
);
1857 CPPUNIT_ASSERT_EQUAL(OUString("nes met joe Sm"), editEng
.GetText(esel
));
1858 CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNes met joe smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1859 CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNes Met Joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1860 CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNES MET JOE SMith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1861 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1863 /* Test behavior when there is a selection that crosses a sentence boundary: "joe Smith. Time Passed." */
1866 esel
= ESelection(0, selStart
, 0, selEnd
);
1867 editEng
.SetText(sText2
);
1868 CPPUNIT_ASSERT_EQUAL(OUString("joe Smith. Time Passed."), editEng
.GetText(esel
));
1870 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met Joe smith. Time passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1871 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met Joe Smith. Time Passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1872 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met JOE SMITH. TIME PASSED."), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1873 CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe smith. time passed."), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1875 /* Test behavior when sentence ends with a capital that is not selected: "CURRENT IS EQUAL TO 10 A" */
1878 esel
= ESelection(0, selStart
, 0, selEnd
);
1879 const OUString
sText3("CURRENT IS EQUAL TO 10 A");
1880 editEng
.SetText(sText3
);
1881 CPPUNIT_ASSERT_EQUAL(OUString("CURRENT IS EQUAL TO"), editEng
.GetText(esel
));
1883 CPPUNIT_ASSERT_EQUAL(OUString("Current is equal to 10 A"), lcl_translitTest(editEng
, sText3
, esel
, TF::SENTENCE_CASE
));
1884 CPPUNIT_ASSERT_EQUAL(OUString("Current Is Equal To 10 A"), lcl_translitTest(editEng
, sText3
, esel
, TF::TITLE_CASE
));
1885 CPPUNIT_ASSERT_EQUAL(OUString("CURRENT IS EQUAL TO 10 A"), lcl_translitTest(editEng
, sText3
, esel
, TF::LOWERCASE_UPPERCASE
));
1886 CPPUNIT_ASSERT_EQUAL(OUString("current is equal to 10 A"), lcl_translitTest(editEng
, sText3
, esel
, TF::UPPERCASE_LOWERCASE
));
1890 void Test::testTdf147196()
1892 EditEngine
editEng( mpItemPool
.get() );
1893 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.");
1894 editEng
.TransliterateText(ESelection(0, 0, 3, 232), TransliterationFlags::TITLE_CASE
);
1895 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());
1898 void Test::testTdf148148()
1900 using TF
= TransliterationFlags
;
1901 EditEngine
editEng( mpItemPool
.get() );
1903 /* Test what happens when node contains text but selection does not contain any text */
1906 ESelection
esel(0, selStart
, 0, selEnd
);
1907 const OUString
sText1(" text");
1908 editEng
.SetText(sText1
);
1909 CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng
.GetText(esel
));
1911 CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng
, sText1
, esel
, TF::SENTENCE_CASE
));
1912 CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng
, sText1
, esel
, TF::TITLE_CASE
));
1913 CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng
, sText1
, esel
, TF::LOWERCASE_UPPERCASE
));
1914 CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng
, sText1
, esel
, TF::UPPERCASE_LOWERCASE
));
1918 esel
= ESelection(0, selStart
, 0, selEnd
);
1919 const OUString
sText2("text ");
1920 editEng
.SetText(sText2
);
1921 CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng
.GetText(esel
));
1923 CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng
, sText2
, esel
, TF::SENTENCE_CASE
));
1924 CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng
, sText2
, esel
, TF::TITLE_CASE
));
1925 CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng
, sText2
, esel
, TF::LOWERCASE_UPPERCASE
));
1926 CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng
, sText2
, esel
, TF::UPPERCASE_LOWERCASE
));
1928 /* Test what happens when node contains only non-word text but selection does not contain any text */
1931 esel
= ESelection(0, selStart
, 0, selEnd
);
1932 const OUString
sText3(" -1");
1933 editEng
.SetText(sText3
);
1934 CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng
.GetText(esel
));
1936 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText3
, esel
, TF::SENTENCE_CASE
));
1937 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText3
, esel
, TF::TITLE_CASE
));
1938 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText3
, esel
, TF::LOWERCASE_UPPERCASE
));
1939 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText3
, esel
, TF::UPPERCASE_LOWERCASE
));
1943 esel
= ESelection(0, selStart
, 0, selEnd
);
1944 const OUString
sText4("-1 ");
1945 editEng
.SetText(sText4
);
1946 CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng
.GetText(esel
));
1948 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText4
, esel
, TF::SENTENCE_CASE
));
1949 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText4
, esel
, TF::TITLE_CASE
));
1950 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText4
, esel
, TF::LOWERCASE_UPPERCASE
));
1951 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText4
, esel
, TF::UPPERCASE_LOWERCASE
));
1953 /* Test what happens when node and selection contains only non-word text */
1956 esel
= ESelection(0, selStart
, 0, selEnd
);
1957 const OUString
sText5(" -1");
1958 editEng
.SetText(sText3
);
1959 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), editEng
.GetText(esel
));
1961 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText5
, esel
, TF::SENTENCE_CASE
));
1962 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText5
, esel
, TF::TITLE_CASE
));
1963 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText5
, esel
, TF::LOWERCASE_UPPERCASE
));
1964 CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng
, sText5
, esel
, TF::UPPERCASE_LOWERCASE
));
1968 esel
= ESelection(0, selStart
, 0, selEnd
);
1969 const OUString
sText6("-1 ");
1970 editEng
.SetText(sText4
);
1971 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), editEng
.GetText(esel
));
1973 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText6
, esel
, TF::SENTENCE_CASE
));
1974 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText6
, esel
, TF::TITLE_CASE
));
1975 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText6
, esel
, TF::LOWERCASE_UPPERCASE
));
1976 CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng
, sText6
, esel
, TF::UPPERCASE_LOWERCASE
));
1981 void Test::testSingleLine()
1983 EditEngine
aEditEngine( mpItemPool
.get() );
1985 aEditEngine
.SetSingleLine(true);
1986 aEditEngine
.SetText("Bolivian\nSanta Cruz de la Sierra");
1987 aEditEngine
.QuickFormatDoc(true);
1988 CPPUNIT_ASSERT_EQUAL(true, aEditEngine
.IsFormatted());
1989 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aEditEngine
.GetParagraphCount());
1990 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aEditEngine
.GetLineCount(0));
1993 CPPUNIT_TEST_SUITE_REGISTRATION(Test
);
1997 CPPUNIT_PLUGIN_IMPLEMENT();
1999 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */