Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
10 : #include "test/bootstrapfixture.hxx"
11 :
12 : #include <cppunit/TestFixture.h>
13 : #include <cppunit/extensions/HelperMacros.h>
14 :
15 : #include "svl/itempool.hxx"
16 : #include "editeng/eerdll.hxx"
17 : #include "editeng/eerdll2.hxx"
18 : #include "editeng/editeng.hxx"
19 : #include "editeng/eeitem.hxx"
20 : #include "editeng/editids.hrc"
21 : #include "editeng/editdoc.hxx"
22 : #include "editeng/svxacorr.hxx"
23 : #include "editeng/unofield.hxx"
24 : #include "editeng/wghtitem.hxx"
25 : #include "editeng/postitem.hxx"
26 : #include "editeng/section.hxx"
27 : #include "editeng/editobj.hxx"
28 : #include "editeng/flditem.hxx"
29 : #include "svl/srchitem.hxx"
30 : #include "rtl/strbuf.hxx"
31 :
32 : #include <com/sun/star/text/textfield/Type.hpp>
33 :
34 : #include <boost/scoped_ptr.hpp>
35 :
36 : using namespace com::sun::star;
37 :
38 : namespace {
39 :
40 20 : class Test : public test::BootstrapFixture
41 : {
42 : public:
43 : Test();
44 :
45 : virtual void setUp() SAL_OVERRIDE;
46 : virtual void tearDown() SAL_OVERRIDE;
47 :
48 : void testConstruction();
49 :
50 : /// Test UNO service class that implements text field items.
51 : void testUnoTextFields();
52 :
53 : /// AutoCorrect tests
54 : void testAutocorrect();
55 :
56 : /// Test hyperlinks
57 : void testHyperlinkSearch();
58 :
59 : void testSectionAttributes();
60 :
61 4 : CPPUNIT_TEST_SUITE(Test);
62 2 : CPPUNIT_TEST(testConstruction);
63 2 : CPPUNIT_TEST(testUnoTextFields);
64 2 : CPPUNIT_TEST(testAutocorrect);
65 2 : CPPUNIT_TEST(testHyperlinkSearch);
66 2 : CPPUNIT_TEST(testSectionAttributes);
67 4 : CPPUNIT_TEST_SUITE_END();
68 :
69 : private:
70 : EditEngineItemPool* mpItemPool;
71 : };
72 :
73 10 : Test::Test() : mpItemPool(NULL) {}
74 :
75 10 : void Test::setUp()
76 : {
77 10 : test::BootstrapFixture::setUp();
78 :
79 10 : mpItemPool = new EditEngineItemPool(true);
80 10 : }
81 :
82 10 : void Test::tearDown()
83 : {
84 10 : SfxItemPool::Free(mpItemPool);
85 10 : test::BootstrapFixture::tearDown();
86 10 : }
87 :
88 2 : void Test::testConstruction()
89 : {
90 2 : EditEngine aEngine(mpItemPool);
91 :
92 4 : OUString aParaText = "I am Edit Engine.";
93 4 : aEngine.SetText(aParaText);
94 2 : }
95 :
96 : namespace {
97 :
98 28 : bool includes(const uno::Sequence<OUString>& rSeq, const OUString& rVal)
99 : {
100 112 : for (sal_Int32 i = 0, n = rSeq.getLength(); i < n; ++i)
101 112 : if (rSeq[i] == rVal)
102 28 : return true;
103 :
104 0 : return false;
105 : }
106 :
107 : }
108 :
109 2 : void Test::testUnoTextFields()
110 : {
111 : {
112 : // DATE
113 2 : SvxUnoTextField aField(text::textfield::Type::DATE);
114 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
115 2 : bool bGood = includes(aSvcs, "com.sun.star.text.textfield.DateTime");
116 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
117 : }
118 :
119 : {
120 : // URL
121 2 : SvxUnoTextField aField(text::textfield::Type::URL);
122 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
123 2 : bool bGood = includes(aSvcs, "com.sun.star.text.textfield.URL");
124 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
125 : }
126 :
127 : {
128 : // PAGE
129 2 : SvxUnoTextField aField(text::textfield::Type::PAGE);
130 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
131 2 : bool bGood = includes(aSvcs, "com.sun.star.text.textfield.PageNumber");
132 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
133 : }
134 :
135 : {
136 : // PAGES
137 2 : SvxUnoTextField aField(text::textfield::Type::PAGES);
138 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
139 2 : bool bGood = includes(aSvcs, "com.sun.star.text.textfield.PageCount");
140 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
141 : }
142 :
143 : {
144 : // TIME
145 2 : SvxUnoTextField aField(text::textfield::Type::TIME);
146 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
147 2 : bool bGood = includes(aSvcs, "com.sun.star.text.textfield.DateTime");
148 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
149 : }
150 :
151 : {
152 : // FILE
153 2 : SvxUnoTextField aField(text::textfield::Type::DOCINFO_TITLE);
154 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
155 2 : bool bGood = includes(aSvcs, "com.sun.star.text.textfield.docinfo.Title");
156 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
157 : }
158 :
159 : {
160 : // TABLE
161 2 : SvxUnoTextField aField(text::textfield::Type::TABLE);
162 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
163 2 : bool bGood = includes(aSvcs, "com.sun.star.text.textfield.SheetName");
164 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
165 : }
166 :
167 : {
168 : // EXTENDED TIME
169 2 : SvxUnoTextField aField(text::textfield::Type::EXTENDED_TIME);
170 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
171 2 : bool bGood = includes(aSvcs, "com.sun.star.text.textfield.DateTime");
172 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
173 : }
174 :
175 : {
176 : // EXTENDED FILE
177 2 : SvxUnoTextField aField(text::textfield::Type::EXTENDED_FILE);
178 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
179 2 : bool bGood = includes(aSvcs, "com.sun.star.text.textfield.FileName");
180 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
181 : }
182 :
183 : {
184 : // AUTHOR
185 2 : SvxUnoTextField aField(text::textfield::Type::AUTHOR);
186 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
187 2 : bool bGood = includes(aSvcs, "com.sun.star.text.textfield.Author");
188 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
189 : }
190 :
191 : {
192 : // MEASURE
193 2 : SvxUnoTextField aField(text::textfield::Type::MEASURE);
194 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
195 2 : bool bGood = includes(aSvcs, "com.sun.star.text.textfield.Measure");
196 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
197 : }
198 :
199 : {
200 : // PRESENTATION HEADER
201 2 : SvxUnoTextField aField(text::textfield::Type::PRESENTATION_HEADER);
202 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
203 2 : bool bGood = includes(aSvcs, "com.sun.star.presentation.textfield.Header");
204 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
205 : }
206 :
207 : {
208 : // PRESENTATION FOOTER
209 2 : SvxUnoTextField aField(text::textfield::Type::PRESENTATION_FOOTER);
210 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
211 2 : bool bGood = includes(aSvcs, "com.sun.star.presentation.textfield.Footer");
212 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
213 : }
214 :
215 : {
216 : // PRESENTATION DATE TIME
217 2 : SvxUnoTextField aField(text::textfield::Type::PRESENTATION_DATE_TIME);
218 4 : uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
219 2 : bool bGood = includes(aSvcs, "com.sun.star.presentation.textfield.DateTime");
220 4 : CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
221 : }
222 2 : }
223 :
224 6 : class TestAutoCorrDoc : public SvxAutoCorrDoc
225 : {
226 : public:
227 : /// just like the real thing, this dummy modifies the rText parameter :(
228 6 : TestAutoCorrDoc(OUString &rText, LanguageType eLang)
229 : : m_rText(rText)
230 6 : , m_eLang(eLang)
231 : {
232 6 : }
233 6 : OUString const& getResult() const
234 : {
235 6 : return m_rText;
236 : }
237 : private:
238 : OUString & m_rText;
239 : LanguageType m_eLang;
240 4 : virtual bool Delete( sal_Int32 nStt, sal_Int32 nEnd ) SAL_OVERRIDE
241 : {
242 : //fprintf(stderr, "TestAutoCorrDoc::Delete\n");
243 4 : m_rText = m_rText.replaceAt(nStt, nEnd-nStt, "");
244 4 : return true;
245 : }
246 6 : virtual bool Insert( sal_Int32 nPos, const OUString& rTxt ) SAL_OVERRIDE
247 : {
248 : //fprintf(stderr, "TestAutoCorrDoc::Insert\n");
249 6 : m_rText = m_rText.replaceAt(nPos, 0, rTxt);
250 6 : return true;
251 : }
252 0 : virtual bool Replace( sal_Int32 nPos, const OUString& rTxt ) SAL_OVERRIDE
253 : {
254 : //fprintf(stderr, "TestAutoCorrDoc::Replace\n");
255 0 : return ReplaceRange( nPos, rTxt.getLength(), rTxt );
256 : }
257 8 : virtual bool ReplaceRange( sal_Int32 nPos, sal_Int32 nLen, const OUString& rTxt ) SAL_OVERRIDE
258 : {
259 : //fprintf(stderr, "TestAutoCorrDoc::ReplaceRange %d %d %s\n", nPos, nLen, OUStringToOString(rTxt, RTL_TEXTENCODING_UTF8).getStr());
260 8 : m_rText = m_rText.replaceAt(nPos, nLen, rTxt);
261 8 : return true;
262 : }
263 2 : virtual bool SetAttr( sal_Int32, sal_Int32, sal_uInt16, SfxPoolItem& ) SAL_OVERRIDE
264 : {
265 : //fprintf(stderr, "TestAutoCorrDoc::SetAttr\n");
266 2 : return true;
267 : }
268 0 : virtual bool SetINetAttr( sal_Int32, sal_Int32, const OUString& ) SAL_OVERRIDE
269 : {
270 : //fprintf(stderr, "TestAutoCorrDoc::SetINetAttr\n");
271 0 : return true;
272 : }
273 0 : virtual OUString const* GetPrevPara(bool) SAL_OVERRIDE
274 : {
275 : //fprintf(stderr, "TestAutoCorrDoc::GetPrevPara\n");
276 0 : return 0;
277 : }
278 4 : virtual bool ChgAutoCorrWord( sal_Int32& rSttPos,
279 : sal_Int32 nEndPos, SvxAutoCorrect& rACorrect,
280 : OUString* pPara ) SAL_OVERRIDE
281 : {
282 : //fprintf(stderr, "TestAutoCorrDoc::ChgAutoCorrWord\n");
283 :
284 4 : if (m_rText.isEmpty())
285 0 : return false;
286 :
287 4 : LanguageTag aLanguageTag( m_eLang);
288 : const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList(
289 4 : m_rText, rSttPos, nEndPos, *this, aLanguageTag);
290 4 : if (pFnd && pFnd->IsTextOnly())
291 : {
292 0 : m_rText = m_rText.replaceAt(rSttPos, nEndPos, pFnd->GetLong());
293 0 : if( pPara )
294 0 : *pPara = "";//&pCurNode->GetString();
295 0 : return true;
296 : }
297 :
298 4 : return false;
299 : }
300 : };
301 :
302 : //https://bugs.libreoffice.org/show_bug.cgi?id=55693
303 : //Two capitalized letters are not corrected if dash or slash are directly
304 : //before the two letters
305 2 : void Test::testAutocorrect()
306 : {
307 2 : OUString sShareAutocorrFile;
308 4 : OUString sUserAutocorrFile;
309 4 : SvxAutoCorrect aAutoCorrect(sShareAutocorrFile, sUserAutocorrFile);
310 :
311 : {
312 2 : OUString sInput("TEst-TEst");
313 2 : sal_Unicode cNextChar(' ');
314 4 : OUString sExpected("Test-Test ");
315 :
316 4 : TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US);
317 2 : aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true);
318 :
319 4 : CPPUNIT_ASSERT_MESSAGE("autocorrect", aFoo.getResult() == sExpected);
320 : }
321 :
322 : {
323 2 : OUString sInput("TEst/TEst");
324 2 : sal_Unicode cNextChar(' ');
325 4 : OUString sExpected("Test/Test ");
326 :
327 4 : TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US);
328 2 : aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true);
329 :
330 4 : CPPUNIT_ASSERT_MESSAGE("autocorrect", aFoo.getResult() == sExpected);
331 : }
332 :
333 : {
334 : // test auto-bolding with '*'
335 2 : OUString sInput("*foo");
336 2 : sal_Unicode cNextChar('*');
337 4 : OUString sExpected("foo");
338 :
339 4 : TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US);
340 2 : aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true);
341 :
342 4 : CPPUNIT_ASSERT_EQUAL(sExpected, aFoo.getResult());
343 2 : }
344 2 : }
345 :
346 : namespace {
347 2 : class UrlEditEngine : public EditEngine
348 : {
349 : public:
350 2 : UrlEditEngine(SfxItemPool *pPool) : EditEngine(pPool) {}
351 :
352 2 : virtual OUString CalcFieldValue( const SvxFieldItem&, sal_Int32, sal_Int32, Color*&, Color*& ) SAL_OVERRIDE
353 : {
354 2 : return OUString("jim@bob.com"); // a sophisticated view of value:
355 : }
356 : };
357 : }
358 :
359 : // Odd accounting for hyperlink position & size etc.
360 : // https://bugzilla.novell.com/show_bug.cgi?id=467459
361 2 : void Test::testHyperlinkSearch()
362 : {
363 2 : UrlEditEngine aEngine(mpItemPool);
364 2 : EditDoc &rDoc = aEngine.GetEditDoc();
365 :
366 4 : OUString aSampleText = "Please write email to . if you find a fish(not a dog).";
367 2 : aEngine.SetText(aSampleText);
368 :
369 2 : CPPUNIT_ASSERT_MESSAGE("set text", rDoc.GetParaAsString(sal_Int32(0)) == aSampleText);
370 :
371 2 : ContentNode *pNode = rDoc.GetObject(0);
372 2 : EditSelection aSel(EditPaM(pNode, 22), EditPaM(pNode, 22));
373 : SvxURLField aURLField("mailto:///jim@bob.com", "jim@bob.com",
374 4 : SVXURLFORMAT_REPR);
375 4 : SvxFieldItem aField(aURLField, EE_FEATURE_FIELD);
376 :
377 2 : aEngine.InsertField(aSel, aField);
378 2 : aEngine.UpdateFields();
379 :
380 4 : OUString aContent = pNode->GetExpandedText();
381 4 : CPPUNIT_ASSERT_MESSAGE("get text", aContent ==
382 2 : "Please write email to jim@bob.com. if you find a fish(not a dog).");
383 2 : CPPUNIT_ASSERT_MESSAGE("wrong length", rDoc.GetTextLen() == (sal_uLong)aContent.getLength());
384 :
385 : // Check expansion and positioning re-work
386 4 : CPPUNIT_ASSERT_MESSAGE("wrong length", pNode->GetExpandedLen() ==
387 2 : (sal_uLong)aContent.getLength());
388 132 : for (sal_Int32 n = 0; n < aContent.getLength(); n++)
389 : {
390 130 : sal_Int32 nStart = n, nEnd = n;
391 130 : pNode->UnExpandPositions(nStart,nEnd);
392 130 : CPPUNIT_ASSERT_MESSAGE("out of bound start", nStart < pNode->Len());
393 130 : CPPUNIT_ASSERT_MESSAGE("out of bound end", nEnd <= pNode->Len());
394 : }
395 :
396 : static const struct {
397 : sal_Int32 mnStart, mnEnd;
398 : sal_Int32 mnNewStart, mnNewEnd;
399 : } aTrickyOnes[] = {
400 : { 0, 1, /* -> */ 0, 1 },
401 : { 21, 25, /* -> */ 21, 23 }, // the field is really just one char
402 : { 25, 27, /* -> */ 22, 23 },
403 : { 50, 56, /* -> */ 40, 46 }
404 : };
405 10 : for (size_t n = 0; n < SAL_N_ELEMENTS(aTrickyOnes); n++)
406 : {
407 8 : sal_Int32 nStart = aTrickyOnes[n].mnStart;
408 8 : sal_Int32 nEnd = aTrickyOnes[n].mnEnd;
409 8 : pNode->UnExpandPositions(nStart,nEnd);
410 :
411 8 : rtl::OStringBuffer aBuf;
412 8 : aBuf = "bound check start is ";
413 8 : aBuf.append(nStart).append(" but should be ").append(aTrickyOnes[n].mnNewStart);
414 8 : aBuf.append(" in row ").append((sal_Int32)n);
415 8 : CPPUNIT_ASSERT_MESSAGE(aBuf.getStr(), nStart == aTrickyOnes[n].mnNewStart);
416 8 : aBuf = "bound check end is ";
417 8 : aBuf.append(nEnd).append(" but should be ").append(aTrickyOnes[n].mnNewEnd);
418 8 : aBuf.append(" in row ").append((sal_Int32)n);
419 8 : CPPUNIT_ASSERT_MESSAGE(aBuf.getStr(), nEnd == aTrickyOnes[n].mnNewEnd);
420 8 : }
421 :
422 4 : SvxSearchItem aItem(1); //SID_SEARCH_ITEM);
423 2 : aItem.SetBackward(false);
424 2 : aItem.SetSelection(false);
425 2 : aItem.SetSearchString("fish");
426 2 : CPPUNIT_ASSERT_MESSAGE("no fish", aEngine.HasText(aItem));
427 2 : aItem.SetSearchString("dog");
428 4 : CPPUNIT_ASSERT_MESSAGE("no dog", aEngine.HasText(aItem));
429 2 : }
430 :
431 10 : bool hasBold(const editeng::Section& rSecAttr)
432 : {
433 10 : std::vector<const SfxPoolItem*>::const_iterator it = rSecAttr.maAttributes.begin(), itEnd = rSecAttr.maAttributes.end();
434 10 : for (; it != itEnd; ++it)
435 : {
436 10 : const SfxPoolItem* p = *it;
437 10 : if (p->Which() != EE_CHAR_WEIGHT)
438 0 : continue;
439 :
440 10 : if (static_cast<const SvxWeightItem*>(p)->GetWeight() != WEIGHT_BOLD)
441 0 : continue;
442 :
443 10 : return true;
444 : }
445 0 : return false;
446 : }
447 :
448 4 : bool hasItalic(const editeng::Section& rSecAttr)
449 : {
450 4 : std::vector<const SfxPoolItem*>::const_iterator it = rSecAttr.maAttributes.begin(), itEnd = rSecAttr.maAttributes.end();
451 6 : for (; it != itEnd; ++it)
452 : {
453 6 : const SfxPoolItem* p = *it;
454 6 : if (p->Which() != EE_CHAR_ITALIC)
455 2 : continue;
456 :
457 4 : if (static_cast<const SvxPostureItem*>(p)->GetPosture() != ITALIC_NORMAL)
458 0 : continue;
459 :
460 4 : return true;
461 : }
462 0 : return false;
463 : }
464 :
465 2 : void Test::testSectionAttributes()
466 : {
467 2 : EditEngine aEngine(mpItemPool);
468 :
469 4 : boost::scoped_ptr<SfxItemSet> pSet(new SfxItemSet(aEngine.GetEmptyItemSet()));
470 4 : SvxWeightItem aBold(WEIGHT_BOLD, EE_CHAR_WEIGHT);
471 4 : SvxPostureItem aItalic(ITALIC_NORMAL, EE_CHAR_ITALIC);
472 :
473 : {
474 2 : OUString aParaText = "aaabbbccc";
475 2 : aEngine.SetText(aParaText);
476 2 : pSet->Put(aBold);
477 2 : CPPUNIT_ASSERT_MESSAGE("There should be exactly one item.", pSet->Count() == 1);
478 2 : aEngine.QuickSetAttribs(*pSet, ESelection(0,0,0,6)); // 'aaabbb' - end point is not inclusive.
479 2 : pSet.reset(new SfxItemSet(aEngine.GetEmptyItemSet()));
480 2 : pSet->Put(aItalic);
481 2 : CPPUNIT_ASSERT_MESSAGE("There should be exactly one item.", pSet->Count() == 1);
482 :
483 2 : aEngine.QuickSetAttribs(*pSet, ESelection(0,3,0,9)); // 'bbbccc'
484 4 : boost::scoped_ptr<EditTextObject> pEditText(aEngine.CreateTextObject());
485 2 : CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText.get());
486 4 : std::vector<editeng::Section> aAttrs;
487 2 : pEditText->GetAllSections(aAttrs);
488 :
489 : // Now, we should have a total of 3 sections.
490 2 : CPPUNIT_ASSERT_MESSAGE("There should be 3 sections.", aAttrs.size() == 3);
491 :
492 : // First section should be 0-3 of paragraph 0, and it should only have boldness applied.
493 2 : const editeng::Section* pSecAttr = &aAttrs[0];
494 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnParagraph);
495 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
496 2 : CPPUNIT_ASSERT_EQUAL(3, (int)pSecAttr->mnEnd);
497 2 : CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->maAttributes.size());
498 2 : CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(*pSecAttr));
499 :
500 : // Second section should be 3-6, and it should be both bold and italic.
501 2 : pSecAttr = &aAttrs[1];
502 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnParagraph);
503 2 : CPPUNIT_ASSERT_EQUAL(3, (int)pSecAttr->mnStart);
504 2 : CPPUNIT_ASSERT_EQUAL(6, (int)pSecAttr->mnEnd);
505 2 : CPPUNIT_ASSERT_EQUAL(2, (int)pSecAttr->maAttributes.size());
506 2 : CPPUNIT_ASSERT_MESSAGE("This section must be bold and italic.", hasBold(*pSecAttr) && hasItalic(*pSecAttr));
507 :
508 : // Third section should be 6-9, and it should be only italic.
509 2 : pSecAttr = &aAttrs[2];
510 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnParagraph);
511 2 : CPPUNIT_ASSERT_EQUAL(6, (int)pSecAttr->mnStart);
512 2 : CPPUNIT_ASSERT_EQUAL(9, (int)pSecAttr->mnEnd);
513 2 : CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->maAttributes.size());
514 4 : CPPUNIT_ASSERT_MESSAGE("This section must be italic.", hasItalic(*pSecAttr));
515 : }
516 :
517 : {
518 : // Set text consisting of 5 paragraphs with the 2nd and 4th paragraphs
519 : // being empty.
520 2 : aEngine.Clear();
521 2 : aEngine.SetText("one\n\ntwo\n\nthree");
522 2 : sal_Int32 nParaCount = aEngine.GetParagraphCount();
523 2 : sal_Int32 nCheck = 5;
524 2 : CPPUNIT_ASSERT_EQUAL(nCheck, nParaCount);
525 :
526 : // Apply boldness to paragraphs 1, 3, 5 only. Leave 2 and 4 unformatted.
527 2 : pSet.reset(new SfxItemSet(aEngine.GetEmptyItemSet()));
528 2 : pSet->Put(aBold);
529 2 : CPPUNIT_ASSERT_MESSAGE("There should be exactly one item.", pSet->Count() == 1);
530 2 : aEngine.QuickSetAttribs(*pSet, ESelection(0,0,0,3));
531 2 : aEngine.QuickSetAttribs(*pSet, ESelection(2,0,2,3));
532 2 : aEngine.QuickSetAttribs(*pSet, ESelection(4,0,4,5));
533 :
534 2 : boost::scoped_ptr<EditTextObject> pEditText(aEngine.CreateTextObject());
535 2 : CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText.get());
536 4 : std::vector<editeng::Section> aAttrs;
537 2 : pEditText->GetAllSections(aAttrs);
538 2 : size_t nSecCountCheck = 5;
539 2 : CPPUNIT_ASSERT_EQUAL(nSecCountCheck, aAttrs.size());
540 :
541 : // 1st, 3rd and 5th sections should correspond with 1st, 3rd and 5th paragraphs.
542 2 : const editeng::Section* pSecAttr = &aAttrs[0];
543 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnParagraph);
544 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
545 2 : CPPUNIT_ASSERT_EQUAL(3, (int)pSecAttr->mnEnd);
546 2 : CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->maAttributes.size());
547 2 : CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(*pSecAttr));
548 :
549 2 : pSecAttr = &aAttrs[2];
550 2 : CPPUNIT_ASSERT_EQUAL(2, (int)pSecAttr->mnParagraph);
551 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
552 2 : CPPUNIT_ASSERT_EQUAL(3, (int)pSecAttr->mnEnd);
553 2 : CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->maAttributes.size());
554 2 : CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(*pSecAttr));
555 :
556 2 : pSecAttr = &aAttrs[4];
557 2 : CPPUNIT_ASSERT_EQUAL(4, (int)pSecAttr->mnParagraph);
558 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
559 2 : CPPUNIT_ASSERT_EQUAL(5, (int)pSecAttr->mnEnd);
560 2 : CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->maAttributes.size());
561 2 : CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(*pSecAttr));
562 :
563 : // The 2nd and 4th paragraphs should be empty.
564 2 : pSecAttr = &aAttrs[1];
565 2 : CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->mnParagraph);
566 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
567 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnEnd);
568 2 : CPPUNIT_ASSERT_MESSAGE("Attribute array should be empty.", pSecAttr->maAttributes.empty());
569 :
570 2 : pSecAttr = &aAttrs[3];
571 2 : CPPUNIT_ASSERT_EQUAL(3, (int)pSecAttr->mnParagraph);
572 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
573 2 : CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnEnd);
574 4 : CPPUNIT_ASSERT_MESSAGE("Attribute array should be empty.", pSecAttr->maAttributes.empty());
575 2 : }
576 2 : }
577 :
578 2 : CPPUNIT_TEST_SUITE_REGISTRATION(Test);
579 :
580 : }
581 :
582 8 : CPPUNIT_PLUGIN_IMPLEMENT();
583 :
584 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|