android: Update app-specific/MIME type icons
[LibreOffice.git] / editeng / qa / unit / core-test.cxx
blob075703266c180c1dd592fc96c9eecf1480d55b6f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <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>
37 #include <memory>
38 #include <editeng/outliner.hxx>
40 using namespace com::sun::star;
42 namespace {
44 class Test : public test::BootstrapFixture
46 public:
47 Test();
49 virtual void setUp() override;
50 virtual void tearDown() override;
52 #if HAVE_MORE_FONTS
53 /// Test text portions position when percentage line spacing is set
54 void testLineSpacing();
55 #endif
57 void testConstruction();
59 /// Test UNO service class that implements text field items.
60 void testUnoTextFields();
62 /// AutoCorrect tests
63 void testAutocorrect();
65 /// Test Copy/Paste with hyperlinks in text using Legacy Format
66 void testHyperlinkCopyPaste();
68 /// Test Copy/Paste using Legacy Format
69 void testCopyPaste();
71 /// Test Copy/Paste with selective selection over multiple paragraphs
72 void testMultiParaSelCopyPaste();
74 /// Test Copy/Paste with Tabs
75 void testTabsCopyPaste();
77 /// Test hyperlinks
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);
109 #if HAVE_MORE_FONTS
110 CPPUNIT_TEST(testLineSpacing);
111 #endif
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();
133 private:
134 rtl::Reference<EditEngineItemPool> mpItemPool;
137 Test::Test() {}
139 void Test::setUp()
141 test::BootstrapFixture::setUp();
143 mpItemPool = new EditEngineItemPool();
145 SfxApplication::GetOrCreate();
148 void Test::tearDown()
150 mpItemPool.clear();
151 test::BootstrapFixture::tearDown();
154 #if HAVE_MORE_FONTS
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)
162 return;
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)));
171 // Set initial text
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);
191 // Set font
192 SvxFontItem aFont(EE_CHAR_FONTINFO);
193 aFont.SetFamilyName("Liberation Sans");
194 pSet->Put(aFont);
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);
202 // Assert changes
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)
226 doTest(6, 12, 15);
228 // Test upper Word limit - 13200% (factor 132)
229 doTest(13200, 33615, 33660);
231 #endif
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)
243 if (s == rVal)
244 return true;
246 return false;
249 void Test::testUnoTextFields()
252 // DATE
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);
260 // URL
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);
268 // PAGE
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);
276 // PAGES
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);
284 // TIME
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);
292 // FILE
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);
300 // TABLE
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);
308 // EXTENDED TIME
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);
316 // EXTENDED FILE
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);
324 // AUTHOR
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);
332 // MEASURE
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
366 public:
367 /// just like the real thing, this dummy modifies the rText parameter :(
368 TestAutoCorrDoc(OUString &rText, LanguageType eLang)
369 : m_rText(rText)
370 , m_eLang(eLang)
373 OUString const& getResult() const
375 return m_rText;
377 private:
378 OUString & m_rText;
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"");
384 return true;
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);
390 return true;
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);
401 return true;
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");
410 return true;
412 virtual OUString const* GetPrevPara(bool) override
414 //fprintf(stderr, "TestAutoCorrDoc::GetPrevPara\n");
415 return nullptr;
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())
424 return false;
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());
432 if( pPara )
433 pPara->clear(); // =&pCurNode->GetString();
434 return true;
437 return false;
439 virtual bool TransliterateRTLWord( sal_Int32& /*rSttPos*/,
440 sal_Int32 /*nEndPos*/, bool /*bApply*/ ) override
442 return false;
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 )
529 if (!pInfo)
530 return;
532 const SvxFieldItem& rField = pInfo->GetField();
533 const SvxFieldData* pField = rField.GetField();
534 if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(pField))
536 // URLField
537 OUString aURL = pURLField->GetURL();
538 switch ( pURLField->GetFormat() )
540 case SvxURLFormat::AppDefault:
541 case SvxURLFormat::Repr:
543 pInfo->SetRepresentation( pURLField->GetRepresentation() );
545 break;
547 case SvxURLFormat::Url:
549 pInfo->SetRepresentation( aURL );
551 break;
554 else
556 OSL_FAIL("Unknown Field");
557 pInfo->SetRepresentation(OUString('?'));
561 void Test::testHyperlinkCopyPaste()
563 // Create Outliner instance
564 Outliner aOutliner(mpItemPool.get(), OutlinerMode
565 ::TextObject);
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
579 // URL 1
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 );
584 // URL 2
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 );
596 // Assert changes
597 CPPUNIT_ASSERT_EQUAL( aTextLen, rDoc.GetTextLen() );
598 CPPUNIT_ASSERT_EQUAL( aParaText, rDoc.GetParaAsString(sal_Int32(0)) );
600 // Insert URL 1
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) );
608 // Insert URL 2
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
616 // Check text
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)) );
620 // Check Field 1
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() );
629 // Check Field 2
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
657 // Field 1
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() );
666 // Field 2
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() ) ;
675 // Field 3
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)) );
697 // Set initial text
698 OUString aText = "This is custom initial text";
699 sal_Int32 aTextLen = aText.getLength();
700 aEditEngine.SetText( aText );
702 // Assert changes
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 );
712 // Assert changes
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();
741 // Assert changes
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 );
753 // Assert changes
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 );
783 // Assert changes
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 );
792 // Assert changes
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 );
800 // Assert changes
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 );
810 // Assert changes
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
817 public:
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",
841 SvxURLFormat::Repr);
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)."),
848 aContent);
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;
865 } aTrickyOnes[] = {
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
942 pSet->Put(aBold);
943 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(1), pSet->Count() );
944 aEditEngine.QuickSetAttribs( *pSet, ESelection(0,2,0,14) );
946 // Assert changes
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()) );
971 pSet->Put(aItalic);
972 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(1), pSet->Count() );
973 aEditEngine.QuickSetAttribs( *pSet, ESelection(0,8,0,18) );
975 // Assert changes
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 );
1017 // Assert changes
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) );
1121 // Assert changes
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 );
1151 // Assert changes
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();
1207 // Assert changes
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 );
1219 // Assert changes
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
1270 pSet->Put(aBold);
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) );
1275 // Assert changes
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()) );
1321 pSet->Put(aItalic);
1322 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(1), pSet->Count() );
1323 aEditEngine.QuickSetAttribs( *pSet, ESelection(0,14,1,9) );
1325 // Assert changes
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 );
1391 // Assert changes
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();
1523 // Assert changes
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 );
1535 // Assert changes
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");
1554 pSet->Put(aBold);
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()));
1558 pSet->Put(aItalic);
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
1595 // being empty.
1596 aEngine.Clear();
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()));
1603 pSet->Put(aBold);
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());
1648 aEngine.Clear();
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()));
1654 pSet->Put(aBold);
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();
1720 // Assert changes
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 );
1740 // Assert changes
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.";
1777 int selStart = 12;
1778 int selEnd = 12;
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'. */
1793 selStart = 14;
1794 selEnd = 14;
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'. */
1803 selStart = 24;
1804 selEnd = 24;
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'. */
1813 selStart = 12;
1814 selEnd = 12;
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" */
1823 selStart = 11;
1824 selEnd = 14;
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" */
1833 selStart = 12;
1834 selEnd = 14;
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 */
1843 selStart = 11;
1844 selEnd = 13;
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" */
1854 selStart = 7;
1855 selEnd = 21;
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." */
1864 selStart = 15;
1865 selEnd = 38;
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" */
1876 selStart = 0;
1877 selEnd = 19;
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 */
1904 int selStart = 0;
1905 int selEnd = 3;
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));
1916 selStart = 4;
1917 selEnd = 8;
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 */
1929 selStart = 0;
1930 selEnd = 3;
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));
1941 selStart = 2;
1942 selEnd = 6;
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 */
1954 selStart = 0;
1955 selEnd = 5;
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));
1966 selStart = 0;
1967 selEnd = 5;
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: */