1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <sal/config.h>
11 #include <test/bootstrapfixture.hxx>
13 #include <com/sun/star/i18n/WordType.hpp>
15 #include <comphelper/processfactory.hxx>
16 #include <i18nutil/transliteration.hxx>
17 #include <editeng/adjustitem.hxx>
18 #include <editeng/boxitem.hxx>
19 #include <editeng/brushitem.hxx>
20 #include <editeng/colritem.hxx>
21 #include <editeng/contouritem.hxx>
22 #include <editeng/crossedoutitem.hxx>
23 #include <editeng/fhgtitem.hxx>
24 #include <editeng/fontitem.hxx>
25 #include <editeng/justifyitem.hxx>
26 #include <editeng/lineitem.hxx>
27 #include <editeng/postitem.hxx>
28 #include <editeng/shdditem.hxx>
29 #include <editeng/udlnitem.hxx>
30 #include <editeng/wghtitem.hxx>
31 #include <svl/intitem.hxx>
32 #include <svx/algitem.hxx>
33 #include <svx/rotmodit.hxx>
34 #include <tools/urlobj.hxx>
35 #include <unotools/tempfile.hxx>
36 #include <unotools/transliterationwrapper.hxx>
38 #include <editeng/langitem.hxx>
39 #include <editeng/charhiddenitem.hxx>
41 #include <sfx2/docfilt.hxx>
42 #include <sfx2/docfile.hxx>
44 #include <xmloff/odffields.hxx>
46 #include <breakit.hxx>
48 #include <IDocumentRedlineAccess.hxx>
49 #include <IDocumentFieldsAccess.hxx>
50 #include <IDocumentStatistics.hxx>
51 #include <cellfml.hxx>
53 #include <docstat.hxx>
54 #include <docufld.hxx>
55 #include <fmtanchr.hxx>
57 #include <shellres.hxx>
58 #include <swscanner.hxx>
60 #include <swtypes.hxx>
62 #include <fmtrfmrk.hxx>
63 #include <fmtinfmt.hxx>
64 #include <fchrfmt.hxx>
66 #include <redline.hxx>
68 #include <modeltoviewhelper.hxx>
72 #include <pagedesc.hxx>
75 #include <tblafmt.hxx>
77 #include <IDocumentMarkAccess.hxx>
78 #include <itabenum.hxx>
80 typedef tools::SvRef
<SwDocShell
> SwDocShellRef
;
82 using namespace ::com::sun::star
;
84 /* Implementation of Swdoc-Test class */
86 class SwDocTest
: public test::BootstrapFixture
94 virtual void setUp() override
;
95 virtual void tearDown() override
;
97 void testTableAutoFormats();
98 void testPageDescName();
99 void testFileNameFields();
101 void testModelToViewHelperPassthrough();
102 void testModelToViewHelperExpandFieldsExpandFootnote();
103 void testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode();
104 void testModelToViewHelperExpandFields();
105 void testModelToViewHelperExpandFieldsReplaceMode();
106 void testModelToViewHelperExpandFieldsHideInvisible();
107 void testModelToViewHelperExpandFieldsHideRedlined();
108 void testModelToViewHelperExpandFieldsHideInvisibleExpandFootnote();
109 void testModelToViewHelperExpandFieldsHideInvisibleExpandFootnoteReplaceMode();
110 void testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnote();
111 void testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnoteReplaceMode();
112 void testModelToViewHelperHideInvisibleHideRedlined();
113 void testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnote();
114 void testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnoteReplaceMode();
115 void testModelToViewHelperExpandFieldsExpandFootnote2();
116 void testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode2();
117 void testSwScanner();
118 void testUserPerceivedCharCount();
119 void testMergePortionsDeleteNotSorted();
120 void testGraphicAnchorDeletion();
121 void testTransliterate();
124 void testIntrusiveRing();
125 void testClientModify();
126 void testBroadcastingModify();
127 void testWriterMultiListener();
128 void test64kPageDescs();
130 void testTableCellComparison();
132 CPPUNIT_TEST_SUITE(SwDocTest
);
134 CPPUNIT_TEST(testTransliterate
);
135 CPPUNIT_TEST(testTableAutoFormats
);
136 CPPUNIT_TEST(testPageDescName
);
137 CPPUNIT_TEST(testFileNameFields
);
138 CPPUNIT_TEST(testDocStat
);
139 CPPUNIT_TEST(testModelToViewHelperPassthrough
);
140 CPPUNIT_TEST(testModelToViewHelperExpandFieldsExpandFootnote
);
141 CPPUNIT_TEST(testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode
);
142 CPPUNIT_TEST(testModelToViewHelperExpandFields
);
143 CPPUNIT_TEST(testModelToViewHelperExpandFieldsReplaceMode
);
144 CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideInvisible
);
145 CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideRedlined
);
146 CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideInvisibleExpandFootnote
);
147 CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideInvisibleExpandFootnoteReplaceMode
);
148 CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnote
);
149 CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnoteReplaceMode
);
150 CPPUNIT_TEST(testModelToViewHelperHideInvisibleHideRedlined
);
151 CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnote
);
152 CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnoteReplaceMode
);
153 CPPUNIT_TEST(testModelToViewHelperExpandFieldsExpandFootnote2
);
154 CPPUNIT_TEST(testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode2
);
155 CPPUNIT_TEST(testSwScanner
);
156 CPPUNIT_TEST(testUserPerceivedCharCount
);
157 CPPUNIT_TEST(testMergePortionsDeleteNotSorted
);
158 CPPUNIT_TEST(testGraphicAnchorDeletion
);
159 CPPUNIT_TEST(testMarkMove
);
160 CPPUNIT_TEST(testFormulas
);
161 CPPUNIT_TEST(testIntrusiveRing
);
162 CPPUNIT_TEST(testClientModify
);
163 CPPUNIT_TEST(testBroadcastingModify
);
164 CPPUNIT_TEST(testWriterMultiListener
);
165 CPPUNIT_TEST(test64kPageDescs
);
166 CPPUNIT_TEST(testTdf92308
);
167 CPPUNIT_TEST(testTableCellComparison
);
168 CPPUNIT_TEST_SUITE_END();
172 SwDocShellRef m_xDocShRef
;
175 void SwDocTest::testPageDescName()
177 ShellResource aShellResources
;
179 std::vector
<OUString
> aResults
;
181 //These names must be unique for each different combination, otherwise
182 //duplicate page description names may exist, which will causes lookup
183 //by name to be incorrect, and so the corresponding export to .odt
184 aResults
.push_back(aShellResources
.GetPageDescName(1, ShellResource::NORMAL_PAGE
));
185 aResults
.push_back(aShellResources
.GetPageDescName(1, ShellResource::FIRST_PAGE
));
186 aResults
.push_back(aShellResources
.GetPageDescName(1, ShellResource::FOLLOW_PAGE
));
188 std::sort(aResults
.begin(), aResults
.end());
189 aResults
.erase(std::unique(aResults
.begin(), aResults
.end()), aResults
.end());
191 CPPUNIT_ASSERT_EQUAL_MESSAGE("GetPageDescName results must be unique", static_cast<size_t>(3), aResults
.size());
194 //See https://bugs.libreoffice.org/show_bug.cgi?id=32463
195 void SwDocTest::testFileNameFields()
197 //Here's a file name with some chars in it that will be %% encoded, when expanding
198 //SwFileNameFields we want to restore the original readable filename
199 utl::TempFileNamed
aTempFile(u
"demo [name]");
200 aTempFile
.EnableKillingFile();
202 INetURLObject
aTempFileURL(aTempFile
.GetURL());
203 OUString sFileURL
= aTempFileURL
.GetMainURL(INetURLObject::DecodeMechanism::NONE
);
204 SfxMedium
aDstMed(sFileURL
, StreamMode::STD_READWRITE
);
206 auto pFilter
= std::make_shared
<SfxFilter
>(
208 OUString(), SfxFilterFlags::NONE
, SotClipboardFormatId::NONE
, OUString(), OUString(),
209 "TEXT", OUString() );
210 aDstMed
.SetFilter(pFilter
);
212 m_xDocShRef
->DoSaveAs(aDstMed
);
213 m_xDocShRef
->DoSaveCompleted(&aDstMed
);
215 const INetURLObject
&rUrlObj
= m_xDocShRef
->GetMedium()->GetURLObject();
217 SwFileNameFieldType
aNameField(*m_pDoc
);
220 OUString
sResult(aNameField
.Expand(FF_NAME
));
221 OUString
sExpected(rUrlObj
.getName(INetURLObject::LAST_SEGMENT
,
222 true,INetURLObject::DecodeMechanism::WithCharset
));
223 CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected Readable FileName", sExpected
, sResult
);
227 OUString
sResult(aNameField
.Expand(FF_PATHNAME
));
228 OUString
sExpected(rUrlObj
.GetFull());
229 CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected Readable FileName", sExpected
, sResult
);
233 OUString
sResult(aNameField
.Expand(FF_PATH
));
234 INetURLObject
aTemp(rUrlObj
);
235 aTemp
.removeSegment();
236 OUString
sExpected(aTemp
.PathToFileName());
237 CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected Readable FileName", sExpected
, sResult
);
241 OUString
sResult(aNameField
.Expand(FF_NAME_NOEXT
));
242 OUString
sExpected(rUrlObj
.getName(INetURLObject::LAST_SEGMENT
,
243 true,INetURLObject::DecodeMechanism::WithCharset
));
245 sExpected
= sExpected
.copy(0, sExpected
.getLength() - 4);
246 CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected Readable FileName", sExpected
, sResult
);
249 m_xDocShRef
->DoInitNew();
252 //See http://lists.freedesktop.org/archives/libreoffice/2011-August/016666.html
253 //Remove unnecessary parameter to IDocumentStatistics::UpdateDocStat for
255 void SwDocTest::testDocStat()
257 CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected initial 0 count", static_cast<sal_uLong
>(0), m_pDoc
->getIDocumentStatistics().GetDocStat().nChar
);
259 SwNodeIndex
aIdx(m_pDoc
->GetNodes().GetEndOfContent(), -1);
262 OUString
sText("Hello World");
263 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sText
);
265 CPPUNIT_ASSERT_EQUAL_MESSAGE("Should still be non-updated 0 count", static_cast<sal_uLong
>(0), m_pDoc
->getIDocumentStatistics().GetDocStat().nChar
);
267 SwDocStat aDocStat
= m_pDoc
->getIDocumentStatistics().GetUpdatedDocStat( false, true );
268 sal_uLong nLen
= static_cast<sal_uLong
>(sText
.getLength());
270 CPPUNIT_ASSERT_EQUAL_MESSAGE("Should now have updated count", nLen
, aDocStat
.nChar
);
272 CPPUNIT_ASSERT_EQUAL_MESSAGE("And cache is updated too", nLen
, m_pDoc
->getIDocumentStatistics().GetDocStat().nChar
);
275 //For UI character counts we should follow UAX#29 and display the user
276 //perceived characters, not the number of codepoints, nor the number of code
277 //units http://unicode.org/reports/tr29/
278 void SwDocTest::testUserPerceivedCharCount()
280 SwBreakIt
*pBreakIter
= SwBreakIt::Get();
282 //Grapheme example, two different unicode code-points perceived by the user as a single
284 static constexpr OUStringLiteral sALEF_QAMATS
= u
"\u05D0\u05B8";
285 sal_Int32 nGraphemeCount
= pBreakIter
->getGraphemeCount(sALEF_QAMATS
);
286 CPPUNIT_ASSERT_EQUAL_MESSAGE("Grapheme Count should be 1", static_cast<sal_Int32
>(1), nGraphemeCount
);
288 //Surrogate pair example, one single unicode code-point (U+1D11E)
289 //represented as two code units in UTF-16
290 static constexpr OUStringLiteral sGCLEF
= u
"\U0001D11E";
291 sal_Int32 nCount
= pBreakIter
->getGraphemeCount(sGCLEF
);
292 CPPUNIT_ASSERT_EQUAL_MESSAGE("Surrogate Pair should be counted as single character", static_cast<sal_Int32
>(1), nCount
);
295 static SwTextNode
* getModelToViewTestDocument(SwDoc
*pDoc
)
297 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
300 SwFormatFootnote aFootnote
;
301 aFootnote
.SetNumStr("foo");
303 pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
304 pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "AAAAA BBBBB ");
305 SwTextNode
* pTextNode
= aPaM
.GetPointNode().GetTextNode();
306 sal_Int32 nPos
= aPaM
.GetPoint()->GetContentIndex();
307 pTextNode
->InsertItem(aFootnote
, nPos
, nPos
);
308 pDoc
->getIDocumentContentOperations().InsertString(aPaM
, " CCCCC ");
309 nPos
= aPaM
.GetPoint()->GetContentIndex();
310 pTextNode
->InsertItem(aFootnote
, nPos
, nPos
);
311 pDoc
->getIDocumentContentOperations().InsertString(aPaM
, " DDDDD");
312 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>((4*5) + 5 + 2), pTextNode
->GetText().getLength());
314 //set start of selection to first B
315 aPaM
.GetPoint()->nContent
.Assign(aPaM
.GetPointContentNode(), 6);
317 //set end of selection to last C
318 aPaM
.GetPoint()->nContent
.Assign(aPaM
.GetPointContentNode(), 14);
319 //set character attribute hidden on range
320 SvxCharHiddenItem
aHidden(true, RES_CHRATR_HIDDEN
);
321 pDoc
->getIDocumentContentOperations().InsertPoolItem(aPaM
, aHidden
);
324 //turn on red-lining and show changes
325 pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
|RedlineFlags::ShowInsert
);
326 CPPUNIT_ASSERT_MESSAGE("redlining should be on", pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
327 CPPUNIT_ASSERT_MESSAGE("redlines should be visible", IDocumentRedlineAccess::IsShowChanges(pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
329 //set start of selection to last A
330 aPaM
.GetPoint()->nContent
.Assign(aPaM
.GetPointContentNode(), 4);
332 //set end of selection to second last B
333 aPaM
.GetPoint()->nContent
.Assign(aPaM
.GetPointContentNode(), 9);
334 pDoc
->getIDocumentContentOperations().DeleteAndJoin(aPaM
); //redline-aware deletion api
340 static SwTextNode
* getModelToViewTestDocument2(SwDoc
*pDoc
)
342 getModelToViewTestDocument(pDoc
);
344 SwNodeIndex
aIdx(pDoc
->GetNodes().GetEndOfContent(), -1);
347 pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
348 pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "AAAAA");
349 IDocumentMarkAccess
* pMarksAccess
= pDoc
->getIDocumentMarkAccess();
350 sw::mark::IFieldmark
*pFieldmark
=
351 pMarksAccess
->makeNoTextFieldBookmark(aPaM
, "test", ODF_FORMDROPDOWN
);
352 CPPUNIT_ASSERT(pFieldmark
);
353 uno::Sequence
< OUString
> vListEntries
{ "BBBBB" };
354 (*pFieldmark
->GetParameters())[ODF_FORMDROPDOWN_LISTENTRY
] <<= vListEntries
;
355 (*pFieldmark
->GetParameters())[ODF_FORMDROPDOWN_RESULT
] <<= sal_Int32(0);
356 pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "CCCCC");
357 SwTextNode
* pTextNode
= aPaM
.GetPointNode().GetTextNode();
358 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(11),
359 pTextNode
->GetText().getLength());
364 void SwDocTest::testModelToViewHelperPassthrough()
366 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
368 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr, ExpandMode::PassThrough
);
369 OUString sViewText
= aModelToViewHelper
.getViewText();
370 OUString sModelText
= pTextNode
->GetText();
371 CPPUNIT_ASSERT_EQUAL(sModelText
, sViewText
);
374 void SwDocTest::testModelToViewHelperExpandFieldsExpandFootnote()
376 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
378 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
379 ExpandMode::ExpandFields
| ExpandMode::ExpandFootnote
);
380 OUString sViewText
= aModelToViewHelper
.getViewText();
381 CPPUNIT_ASSERT_EQUAL(
382 OUString("AAAAA BBBBB foo CCCCC foo DDDDD"), sViewText
);
385 void SwDocTest::testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode()
387 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
389 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
390 ExpandMode::ExpandFields
| ExpandMode::ExpandFootnote
| ExpandMode::ReplaceMode
);
391 OUString sViewText
= aModelToViewHelper
.getViewText();
392 CPPUNIT_ASSERT_EQUAL(
393 OUString("AAAAA BBBBB " + OUStringChar(CHAR_ZWSP
) + " CCCCC " + OUStringChar(CHAR_ZWSP
) + " DDDDD"),
395 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2),
396 aModelToViewHelper
.getFootnotePositions().size());
397 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(12),
398 aModelToViewHelper
.getFootnotePositions()[0]);
399 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(20),
400 aModelToViewHelper
.getFootnotePositions()[1]);
401 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
402 aModelToViewHelper
.getFieldPositions().size());
405 void SwDocTest::testModelToViewHelperExpandFields()
407 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
409 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr, ExpandMode::ExpandFields
);
410 OUString sViewText
= aModelToViewHelper
.getViewText();
411 CPPUNIT_ASSERT_EQUAL(
412 OUString("AAAAA BBBBB CCCCC DDDDD"), sViewText
);
415 void SwDocTest::testModelToViewHelperExpandFieldsReplaceMode()
417 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
419 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
420 ExpandMode::ExpandFields
| ExpandMode::ReplaceMode
);
421 OUString sViewText
= aModelToViewHelper
.getViewText();
422 CPPUNIT_ASSERT_EQUAL(OUString("AAAAA BBBBB CCCCC DDDDD"),
424 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
425 aModelToViewHelper
.getFootnotePositions().size());
426 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
427 aModelToViewHelper
.getFieldPositions().size());
430 void SwDocTest::testModelToViewHelperExpandFieldsHideInvisible()
432 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
434 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr, ExpandMode::HideInvisible
);
435 OUString sViewText
= aModelToViewHelper
.getViewText();
436 CPPUNIT_ASSERT_EQUAL(
437 OUString("AAAAA CCCCC " + OUStringChar(CH_TXTATR_BREAKWORD
) + " DDDDD"),
441 void SwDocTest::testModelToViewHelperExpandFieldsHideRedlined()
443 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
445 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr, ExpandMode::HideDeletions
);
446 OUString sViewText
= aModelToViewHelper
.getViewText();
447 CPPUNIT_ASSERT_EQUAL(
448 OUString("AAAABB " + OUStringChar(CH_TXTATR_BREAKWORD
) + " CCCCC " + OUStringChar(CH_TXTATR_BREAKWORD
) + " DDDDD"),
452 void SwDocTest::testModelToViewHelperExpandFieldsHideInvisibleExpandFootnote()
454 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
456 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
457 ExpandMode::ExpandFields
| ExpandMode::HideInvisible
| ExpandMode::ExpandFootnote
);
458 OUString sViewText
= aModelToViewHelper
.getViewText();
459 CPPUNIT_ASSERT_EQUAL(OUString("AAAAA CCCCC foo DDDDD"), sViewText
);
462 void SwDocTest::testModelToViewHelperExpandFieldsHideInvisibleExpandFootnoteReplaceMode()
464 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
466 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
467 ExpandMode::ExpandFields
| ExpandMode::HideInvisible
| ExpandMode::ExpandFootnote
| ExpandMode::ReplaceMode
);
468 OUString sViewText
= aModelToViewHelper
.getViewText();
469 CPPUNIT_ASSERT_EQUAL(
470 OUString("AAAAA CCCCC " + OUStringChar(CHAR_ZWSP
) + " DDDDD"),
472 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1),
473 aModelToViewHelper
.getFootnotePositions().size());
474 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(12),
475 aModelToViewHelper
.getFootnotePositions()[0]);
476 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
477 aModelToViewHelper
.getFieldPositions().size());
480 void SwDocTest::testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnote()
482 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
484 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
485 ExpandMode::ExpandFields
| ExpandMode::HideDeletions
| ExpandMode::ExpandFootnote
);
486 OUString sViewText
= aModelToViewHelper
.getViewText();
487 CPPUNIT_ASSERT_EQUAL(
488 OUString("AAAABB foo CCCCC foo DDDDD"), sViewText
);
491 void SwDocTest::testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnoteReplaceMode()
493 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
495 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
496 ExpandMode::ExpandFields
| ExpandMode::HideDeletions
| ExpandMode::ExpandFootnote
| ExpandMode::ReplaceMode
);
497 OUString sViewText
= aModelToViewHelper
.getViewText();
498 CPPUNIT_ASSERT_EQUAL(
499 OUString("AAAABB " + OUStringChar(CHAR_ZWSP
) + " CCCCC " + OUStringChar(CHAR_ZWSP
) + " DDDDD"),
501 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2),
502 aModelToViewHelper
.getFootnotePositions().size());
503 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(7),
504 aModelToViewHelper
.getFootnotePositions()[0]);
505 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(15),
506 aModelToViewHelper
.getFootnotePositions()[1]);
507 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
508 aModelToViewHelper
.getFieldPositions().size());
511 void SwDocTest::testModelToViewHelperHideInvisibleHideRedlined()
513 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
515 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
516 ExpandMode::HideInvisible
| ExpandMode::HideDeletions
);
517 OUString sViewText
= aModelToViewHelper
.getViewText();
518 OUString aBuffer
= "AAAACCCCC " +
519 OUStringChar(CH_TXTATR_BREAKWORD
) +
521 CPPUNIT_ASSERT_EQUAL(aBuffer
, sViewText
);
524 void SwDocTest::testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnote()
526 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
528 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
529 ExpandMode::ExpandFields
| ExpandMode::HideInvisible
| ExpandMode::HideDeletions
| ExpandMode::ExpandFootnote
);
530 OUString sViewText
= aModelToViewHelper
.getViewText();
531 CPPUNIT_ASSERT_EQUAL(OUString("AAAACCCCC foo DDDDD"), sViewText
);
534 void SwDocTest::testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnoteReplaceMode()
536 SwTextNode
* pTextNode
= getModelToViewTestDocument(m_pDoc
);
538 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
539 ExpandMode::ExpandFields
| ExpandMode::HideInvisible
| ExpandMode::HideDeletions
| ExpandMode::ExpandFootnote
| ExpandMode::ReplaceMode
);
540 OUString sViewText
= aModelToViewHelper
.getViewText();
541 CPPUNIT_ASSERT_EQUAL(sViewText
,
542 OUString("AAAACCCCC " + OUStringChar(CHAR_ZWSP
) + " DDDDD"));
543 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1),
544 aModelToViewHelper
.getFootnotePositions().size());
545 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(10),
546 aModelToViewHelper
.getFootnotePositions()[0]);
547 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
548 aModelToViewHelper
.getFieldPositions().size());
551 void SwDocTest::testModelToViewHelperExpandFieldsExpandFootnote2()
553 SwTextNode
* pTextNode
= getModelToViewTestDocument2(m_pDoc
);
555 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
556 ExpandMode::ExpandFields
| ExpandMode::ExpandFootnote
);
557 OUString sViewText
= aModelToViewHelper
.getViewText();
558 CPPUNIT_ASSERT_EQUAL(OUString("AAAAABBBBBCCCCC"), sViewText
);
561 void SwDocTest::testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode2()
563 SwTextNode
* pTextNode
= getModelToViewTestDocument2(m_pDoc
);
565 ModelToViewHelper
aModelToViewHelper(*pTextNode
, nullptr,
566 ExpandMode::ExpandFields
| ExpandMode::ExpandFootnote
| ExpandMode::ReplaceMode
);
567 OUString sViewText
= aModelToViewHelper
.getViewText();
568 CPPUNIT_ASSERT_EQUAL(
569 OUString("AAAAA" + OUStringChar(CHAR_ZWSP
) + "CCCCC"),
571 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
572 aModelToViewHelper
.getFootnotePositions().size());
573 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1),
574 aModelToViewHelper
.getFieldPositions().size());
575 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(5),
576 aModelToViewHelper
.getFieldPositions()[0]);
579 void SwDocTest::testSwScanner()
581 SwNodeIndex
aIdx(m_pDoc
->GetNodes().GetEndOfContent(), -1);
584 SwTextNode
* pTextNode
= aPaM
.GetPointNode().GetTextNode();
586 CPPUNIT_ASSERT_MESSAGE("Has Text Node", pTextNode
);
588 //See https://bugs.libreoffice.org/show_bug.cgi?id=40449
589 //See https://bugs.libreoffice.org/show_bug.cgi?id=39365
590 //Use a temporary OUString as the arg, as that's the trouble behind
591 //fdo#40449 and fdo#39365
593 SwScanner
aScanner(*pTextNode
,
595 nullptr, ModelToViewHelper(), i18n::WordType::DICTIONARY_WORD
, 0,
596 RTL_CONSTASCII_LENGTH("Hello World"));
598 bool bFirstOk
= aScanner
.NextWord();
599 CPPUNIT_ASSERT_MESSAGE("First Token", bFirstOk
);
600 const OUString
&rHello
= aScanner
.GetWord();
601 CPPUNIT_ASSERT_EQUAL(OUString("Hello"), rHello
);
603 bool bSecondOk
= aScanner
.NextWord();
604 CPPUNIT_ASSERT_MESSAGE("Second Token", bSecondOk
);
605 const OUString
&rWorld
= aScanner
.GetWord();
606 CPPUNIT_ASSERT_EQUAL(OUString("World"), rWorld
);
609 //See https://www.libreoffice.org/bugzilla/show_bug.cgi?id=45271
611 static constexpr OUStringLiteral IDEOGRAPHICFULLSTOP_D
= u
"\u3002D";
613 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, IDEOGRAPHICFULLSTOP_D
);
615 SvxLanguageItem
aCJKLangItem( LANGUAGE_CHINESE_SIMPLIFIED
, RES_CHRATR_CJK_LANGUAGE
);
616 SvxLanguageItem
aWestLangItem( LANGUAGE_ENGLISH_US
, RES_CHRATR_LANGUAGE
);
617 m_pDoc
->getIDocumentContentOperations().InsertPoolItem(aPaM
, aCJKLangItem
);
618 m_pDoc
->getIDocumentContentOperations().InsertPoolItem(aPaM
, aWestLangItem
);
621 pTextNode
= aPaM
.GetPointNode().GetTextNode();
622 pTextNode
->CountWords(aDocStat
, 0, IDEOGRAPHICFULLSTOP_D
.getLength());
624 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(2), aDocStat
.nChar
);
625 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(2), aDocStat
.nCharExcludingSpaces
);
628 static constexpr OUStringLiteral test
=
629 u
"\u3053\u306E\u65E5\u672C\u8A9E\u306F\u6B63\u3057"
630 "\u304F\u6570\u3048\u3089\u308C\u308B\u3067\u3057"
631 "\u3087\u3046\u304B\u3002And "
638 "ng. \u305D\u3057\u3066"
639 "\u3001\u307E\u305F\u65E5\u672C\u8A9E\u3000\u3000"
640 "\u3067\u3082\u4ECA\u56DE\u306F\u7A7A\u767D\u3092"
641 "\u3000\u3000\u5165\u308C\u307E\u3057\u305F\u3002"
645 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
646 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, test
);
648 SvxLanguageItem
aCJKLangItem( LANGUAGE_JAPANESE
, RES_CHRATR_CJK_LANGUAGE
);
649 SvxLanguageItem
aWestLangItem( LANGUAGE_ENGLISH_US
, RES_CHRATR_LANGUAGE
);
650 m_pDoc
->getIDocumentContentOperations().InsertPoolItem(aPaM
, aCJKLangItem
);
651 m_pDoc
->getIDocumentContentOperations().InsertPoolItem(aPaM
, aWestLangItem
);
654 pTextNode
= aPaM
.GetPointNode().GetTextNode();
655 pTextNode
->CountWords(aDocStat
, 0, test
.getLength());
656 CPPUNIT_ASSERT_EQUAL_MESSAGE("words", static_cast<sal_uLong
>(58), aDocStat
.nWord
);
657 CPPUNIT_ASSERT_EQUAL_MESSAGE("Asian characters and Korean syllables", static_cast<sal_uLong
>(43), aDocStat
.nAsianWord
);
658 CPPUNIT_ASSERT_EQUAL_MESSAGE("non-whitespace chars", static_cast<sal_uLong
>(105), aDocStat
.nCharExcludingSpaces
);
659 CPPUNIT_ASSERT_EQUAL_MESSAGE("characters", static_cast<sal_uLong
>(128), aDocStat
.nChar
);
662 //See https://bz.apache.org/ooo/show_bug.cgi?id=89042
663 //See https://bugs.libreoffice.org/show_bug.cgi?id=53399
667 static constexpr OUStringLiteral aShouldBeThree
=
672 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
673 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, aShouldBeThree
);
674 pTextNode
= aPaM
.GetPointNode().GetTextNode();
675 pTextNode
->CountWords(aDocStat
, 0, aShouldBeThree
.getLength());
676 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(3), aDocStat
.nWord
);
678 static constexpr OUStringLiteral aShouldBeFive
=
687 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
688 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, aShouldBeFive
);
689 pTextNode
= aPaM
.GetPointNode().GetTextNode();
691 pTextNode
->CountWords(aDocStat
, 0, aShouldBeFive
.getLength());
692 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(5), aDocStat
.nWord
);
695 //See https://bugs.libreoffice.org/show_bug.cgi?id=49629
699 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
700 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "Apple");
701 pTextNode
= aPaM
.GetPointNode().GetTextNode();
702 sal_Int32 nPos
= aPaM
.GetPoint()->GetContentIndex();
703 SwFormatFootnote aFootnote
;
704 aFootnote
.SetNumStr("banana");
705 SwTextAttr
* pTA
= pTextNode
->InsertItem(aFootnote
, nPos
, nPos
);
707 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(6), pTextNode
->Len()); //Apple + 0x02
708 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
709 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(1), aDocStat
.nWord
);
710 CPPUNIT_ASSERT_EQUAL_MESSAGE("footnote should be expanded", static_cast<sal_uLong
>(11), aDocStat
.nChar
);
712 const sal_Int32 nNextPos
= aPaM
.GetPoint()->GetContentIndex();
713 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(nPos
+1), nNextPos
);
714 SwFormatRefMark
aRef("refmark");
715 pTA
= pTextNode
->InsertItem(aRef
, nNextPos
, nNextPos
);
719 pTextNode
->SetWordCountDirty(true);
720 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
721 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(1), aDocStat
.nWord
);
722 CPPUNIT_ASSERT_EQUAL_MESSAGE("refmark anchor should not be counted", static_cast<sal_uLong
>(11), aDocStat
.nChar
);
724 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
725 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "Apple");
727 DateTime
aDate(DateTime::SYSTEM
);
728 SwPostItField
aPostIt(
729 static_cast<SwPostItFieldType
*>(m_pDoc
->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Postit
)), "An Author",
730 "Some Text", "Initials", "Name", aDate
);
731 m_pDoc
->getIDocumentContentOperations().InsertPoolItem(aPaM
, SwFormatField(aPostIt
));
733 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "Apple");
734 pTextNode
= aPaM
.GetPointNode().GetTextNode();
736 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
737 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(1), aDocStat
.nWord
);
738 CPPUNIT_ASSERT_EQUAL_MESSAGE("postit anchor should effectively not exist", static_cast<sal_uLong
>(10), aDocStat
.nChar
);
739 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(11), pTextNode
->Len());
744 //See https://bugs.libreoffice.org/show_bug.cgi?id=46757
748 static constexpr OUStringLiteral aString
= u
"Lorem ipsum";
749 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
750 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, aString
);
751 pTextNode
= aPaM
.GetPointNode().GetTextNode();
752 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
753 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(2), aDocStat
.nWord
);
755 //turn on red-lining and show changes
756 m_pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
|RedlineFlags::ShowInsert
);
757 CPPUNIT_ASSERT_MESSAGE("redlining should be on", m_pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
758 CPPUNIT_ASSERT_MESSAGE("redlines should be visible", IDocumentRedlineAccess::IsShowChanges(m_pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
760 //delete everything except the first word
761 aPaM
.SetMark(); //set start of selection to current pos
762 aPaM
.GetPoint()->nContent
.Assign(aPaM
.GetPointContentNode(), 5); //set end of selection to fifth char of current node
763 m_pDoc
->getIDocumentContentOperations().DeleteAndJoin(aPaM
); //redline-aware deletion api
764 //"real underlying text should be the same"
765 CPPUNIT_ASSERT_EQUAL(pTextNode
->GetText(), OUString(aString
));
768 pTextNode
->SetWordCountDirty(true);
769 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len()); //but word-counting the text should only count the non-deleted text
770 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(1), aDocStat
.nWord
);
772 pTextNode
->SetWordCountDirty(true);
774 //keep red-lining on but hide changes
775 m_pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
);
776 CPPUNIT_ASSERT_MESSAGE("redlining should be still on", m_pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
777 CPPUNIT_ASSERT_MESSAGE("redlines should be invisible", !IDocumentRedlineAccess::IsShowChanges(m_pDoc
->getIDocumentRedlineAccess().GetRedlineFlags()));
780 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len()); //but word-counting the text should only count the non-deleted text
781 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(1), aDocStat
.nWord
);
783 OUString sLorem
= pTextNode
->GetText();
784 CPPUNIT_ASSERT_EQUAL(OUString("Lorem"), sLorem
);
786 const SwRedlineTable
& rTable
= m_pDoc
->getIDocumentRedlineAccess().GetRedlineTable();
788 SwNodes
& rNds
= m_pDoc
->GetNodes();
789 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), rTable
.size());
791 const SwNodeIndex
* pNodeIdx
= rTable
[0]->GetContentIdx();
792 CPPUNIT_ASSERT(pNodeIdx
);
794 pTextNode
= rNds
[ pNodeIdx
->GetIndex() + 1 ]->GetTextNode(); //first deleted txtnode
795 CPPUNIT_ASSERT(pTextNode
);
797 OUString sIpsum
= pTextNode
->GetText();
798 CPPUNIT_ASSERT_EQUAL(OUString(" ipsum"), sIpsum
);
801 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len()); //word-counting the text should only count the non-deleted text, and this whole chunk should be ignored
802 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(0), aDocStat
.nWord
);
803 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(0), aDocStat
.nChar
);
805 // https://bugs.libreoffice.org/show_bug.cgi?id=68347 we do want to count
806 // redline *added* text though
807 m_pDoc
->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On
| RedlineFlags::ShowDelete
|RedlineFlags::ShowInsert
);
809 aPaM
.GetPoint()->nContent
.Assign(aPaM
.GetPointContentNode(), 0);
810 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "redline-new-text ");
812 pTextNode
= aPaM
.GetPointNode().GetTextNode();
813 pTextNode
->SetWordCountDirty(true);
814 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
815 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(2), aDocStat
.nWord
);
816 //redline-new-text Lorem ipsum
817 //+++++++++++++++++ ------
818 //select start of original text and part of deleted text
820 pTextNode
->CountWords(aDocStat
, 17, 25);
821 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong
>(5), aDocStat
.nChar
);
824 //See https://bugs.libreoffice.org/show_bug.cgi?id=38983
828 OUString
sTemplate("ThisXis a test.");
830 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
831 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sTemplate
.replace('X', ' '));
832 pTextNode
= aPaM
.GetPointNode().GetTextNode();
833 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
834 CPPUNIT_ASSERT_EQUAL(sal_uLong(4), aDocStat
.nWord
);
835 CPPUNIT_ASSERT_EQUAL(sal_uLong(12), aDocStat
.nCharExcludingSpaces
);
836 CPPUNIT_ASSERT_EQUAL(sal_uLong(15), aDocStat
.nChar
);
839 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
840 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sTemplate
.replaceAll("X", " = "));
841 pTextNode
= aPaM
.GetPointNode().GetTextNode();
842 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
843 CPPUNIT_ASSERT_EQUAL(sal_uLong(5), aDocStat
.nWord
);
844 CPPUNIT_ASSERT_EQUAL(sal_uLong(13), aDocStat
.nCharExcludingSpaces
);
845 CPPUNIT_ASSERT_EQUAL(sal_uLong(17), aDocStat
.nChar
);
848 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
849 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sTemplate
.replaceAll("X", " _ "));
850 pTextNode
= aPaM
.GetPointNode().GetTextNode();
851 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
852 CPPUNIT_ASSERT_EQUAL(sal_uLong(5), aDocStat
.nWord
);
853 CPPUNIT_ASSERT_EQUAL(sal_uLong(13), aDocStat
.nCharExcludingSpaces
);
854 CPPUNIT_ASSERT_EQUAL(sal_uLong(17), aDocStat
.nChar
);
857 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
858 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sTemplate
.replaceAll("X", " -- "));
859 pTextNode
= aPaM
.GetPointNode().GetTextNode();
860 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
861 CPPUNIT_ASSERT_EQUAL(sal_uLong(5), aDocStat
.nWord
);
862 CPPUNIT_ASSERT_EQUAL(sal_uLong(14), aDocStat
.nCharExcludingSpaces
);
863 CPPUNIT_ASSERT_EQUAL(sal_uLong(18), aDocStat
.nChar
);
866 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
867 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sTemplate
.replace('X', '_'));
868 pTextNode
= aPaM
.GetPointNode().GetTextNode();
869 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
870 CPPUNIT_ASSERT_EQUAL(sal_uLong(3), aDocStat
.nWord
);
871 CPPUNIT_ASSERT_EQUAL(sal_uLong(13), aDocStat
.nCharExcludingSpaces
);
872 CPPUNIT_ASSERT_EQUAL(sal_uLong(15), aDocStat
.nChar
);
875 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
876 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sTemplate
.replace('X', '-'));
877 pTextNode
= aPaM
.GetPointNode().GetTextNode();
878 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
879 CPPUNIT_ASSERT_EQUAL(sal_uLong(3), aDocStat
.nWord
);
880 CPPUNIT_ASSERT_EQUAL(sal_uLong(13), aDocStat
.nCharExcludingSpaces
);
881 CPPUNIT_ASSERT_EQUAL(sal_uLong(15), aDocStat
.nChar
);
884 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
885 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sTemplate
.replace('X', 0x2012));
886 pTextNode
= aPaM
.GetPointNode().GetTextNode();
887 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
888 CPPUNIT_ASSERT_EQUAL(sal_uLong(3), aDocStat
.nWord
);
889 CPPUNIT_ASSERT_EQUAL(sal_uLong(13), aDocStat
.nCharExcludingSpaces
);
890 CPPUNIT_ASSERT_EQUAL(sal_uLong(15), aDocStat
.nChar
);
893 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
894 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sTemplate
.replace('X', 0x2015));
895 pTextNode
= aPaM
.GetPointNode().GetTextNode();
896 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
897 CPPUNIT_ASSERT_EQUAL(sal_uLong(3), aDocStat
.nWord
);
898 CPPUNIT_ASSERT_EQUAL(sal_uLong(13), aDocStat
.nCharExcludingSpaces
);
899 CPPUNIT_ASSERT_EQUAL(sal_uLong(15), aDocStat
.nChar
);
902 //But default configuration should, msword-alike treat emdash
903 //and endash as word separators for word-counting
904 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
905 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sTemplate
.replace('X', 0x2013));
906 pTextNode
= aPaM
.GetPointNode().GetTextNode();
907 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
908 CPPUNIT_ASSERT_EQUAL(sal_uLong(4), aDocStat
.nWord
);
909 CPPUNIT_ASSERT_EQUAL(sal_uLong(13), aDocStat
.nCharExcludingSpaces
);
910 CPPUNIT_ASSERT_EQUAL(sal_uLong(15), aDocStat
.nChar
);
913 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
914 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sTemplate
.replace('X', 0x2014));
915 pTextNode
= aPaM
.GetPointNode().GetTextNode();
916 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
917 CPPUNIT_ASSERT_EQUAL(sal_uLong(4), aDocStat
.nWord
);
918 CPPUNIT_ASSERT_EQUAL(sal_uLong(13), aDocStat
.nCharExcludingSpaces
);
919 CPPUNIT_ASSERT_EQUAL(sal_uLong(15), aDocStat
.nChar
);
922 static constexpr OUStringLiteral sChunk
= u
" \u2013 ";
923 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
924 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, sTemplate
.replaceAll("X", sChunk
));
925 pTextNode
= aPaM
.GetPointNode().GetTextNode();
926 pTextNode
->CountWords(aDocStat
, 0, pTextNode
->Len());
927 CPPUNIT_ASSERT_EQUAL(sal_uLong(4), aDocStat
.nWord
);
928 CPPUNIT_ASSERT_EQUAL(sal_uLong(13), aDocStat
.nCharExcludingSpaces
);
929 CPPUNIT_ASSERT_EQUAL(sal_uLong(17), aDocStat
.nChar
);
934 void SwDocTest::testMergePortionsDeleteNotSorted()
936 SwNodeIndex
aIdx(m_pDoc
->GetNodes().GetEndOfContent(), -1);
938 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, " AABBCC");
940 SwCharFormat
*const pCharFormat(m_pDoc
->MakeCharFormat("foo", nullptr));
941 SwFormatCharFormat
const charFormat(pCharFormat
);
943 SwFormatINetFormat
const inetFormat("http://example.com", "");
945 IDocumentContentOperations
& rIDCO(m_pDoc
->getIDocumentContentOperations());
947 aPaM
.GetPoint()->nContent
= 2;
948 aPaM
.GetMark()->nContent
= 4;
949 rIDCO
.InsertPoolItem(aPaM
, charFormat
);
950 aPaM
.GetPoint()->nContent
= 2;
951 aPaM
.GetMark()->nContent
= 5;
952 rIDCO
.InsertPoolItem(aPaM
, inetFormat
);
953 aPaM
.GetPoint()->nContent
= 6;
954 aPaM
.GetMark()->nContent
= 8;
955 rIDCO
.InsertPoolItem(aPaM
, charFormat
);
956 aPaM
.GetPoint()->nContent
= 4;
957 aPaM
.GetMark()->nContent
= 6;
958 // this triggered an STL assert in SwpHints::MergePortions()
959 rIDCO
.InsertPoolItem(aPaM
, charFormat
);
962 //See https://bugs.libreoffice.org/show_bug.cgi?id=40599
963 void SwDocTest::testGraphicAnchorDeletion()
965 CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected initial 0 count", static_cast<sal_uLong
>(0), m_pDoc
->getIDocumentStatistics().GetDocStat().nChar
);
967 SwNodeIndex
aIdx(m_pDoc
->GetNodes().GetEndOfContent(), -1);
970 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "Paragraph 1");
971 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
973 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "graphic anchor>><<graphic anchor");
974 SwNodeIndex
nPara2(aPaM
.GetPoint()->GetNode());
975 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
977 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "Paragraph 3");
979 aPaM
.GetPoint()->Assign(nPara2
);
980 aPaM
.GetPoint()->SetContent(RTL_CONSTASCII_LENGTH("graphic anchor>>"));
982 //Insert a graphic at X of >>X<< in paragraph 2
983 SfxItemSet
aFlySet(m_pDoc
->GetAttrPool(), svl::Items
<RES_FRMATR_BEGIN
, RES_FRMATR_END
-1>);
984 SwFormatAnchor
aAnchor(RndStdIds::FLY_AS_CHAR
);
985 aAnchor
.SetAnchor(aPaM
.GetPoint());
986 aFlySet
.Put(aAnchor
);
987 SwFlyFrameFormat
*pFrame
= m_pDoc
->getIDocumentContentOperations().InsertGraphic(aPaM
, OUString(), OUString(), nullptr, &aFlySet
, nullptr, nullptr);
988 CPPUNIT_ASSERT_MESSAGE("Expected frame", pFrame
!= nullptr);
990 CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be 1 graphic", static_cast<size_t>(1), m_pDoc
->GetFlyCount(FLYCNTTYPE_GRF
));
993 aPaM
.GetPoint()->Assign(nPara2
);
994 aPaM
.GetPoint()->SetContent(
995 RTL_CONSTASCII_LENGTH("graphic anchor>><")+1);
997 aPaM
.GetPoint()->Assign(nPara2
);
998 aPaM
.GetPoint()->SetContent(RTL_CONSTASCII_LENGTH("graphic anchor>"));
999 m_pDoc
->getIDocumentContentOperations().DeleteRange(aPaM
);
1001 #ifdef DEBUG_AS_HTML
1003 SvFileStream
aPasteDebug(OUString("cppunitDEBUG.html"), StreamMode::WRITE
|StreamMode::TRUNC
);
1005 GetHTMLWriter( String(), String(), xWrt
);
1006 SwWriter
aDbgWrt( aPasteDebug
, *m_pDoc
);
1007 aDbgWrt
.Write( xWrt
);
1011 CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be 0 graphics", static_cast<size_t>(0), m_pDoc
->GetFlyCount(FLYCNTTYPE_GRF
));
1013 //Now, if instead we swap RndStdIds::FLY_AS_CHAR (inline graphic) to RndStdIds::FLY_AT_CHAR (anchored to character)
1014 //and repeat the above, graphic is *not* deleted, i.e. it belongs to the paragraph, not the
1015 //range to which its anchored, which is annoying.
1018 void SwDocTest::testTableAutoFormats()
1020 SwGlobals::ensure();
1022 //create new AutoFormatTable
1023 SwTableAutoFormatTable aTableAFT
;
1025 //check the style size - default is expected
1026 CPPUNIT_ASSERT_EQUAL( size_t(1), aTableAFT
.size() );
1029 SwTableAutoFormat
aTableAF( "TestItemStyle" );
1031 //create new AutoFormat
1032 SwBoxAutoFormat aBoxAF
;
1035 SvxFontItem
aFont( RES_CHRATR_FONT
);
1036 aFont
.SetFamily( FontFamily::FAMILY_DECORATIVE
);
1037 aFont
.SetPitch( FontPitch::PITCH_VARIABLE
);
1038 aFont
.SetCharSet( RTL_TEXTENCODING_MS_1251
);
1039 aBoxAF
.SetFont( aFont
);
1041 SvxFontHeightItem
aHeight( 280, 120, RES_CHRATR_FONTSIZE
);
1042 aBoxAF
.SetHeight( aHeight
);
1044 SvxWeightItem
aWeight( FontWeight::WEIGHT_BOLD
, RES_CHRATR_WEIGHT
);
1045 aBoxAF
.SetWeight( aWeight
);
1047 SvxPostureItem
aPosture( FontItalic::ITALIC_NORMAL
, RES_CHRATR_POSTURE
);
1048 aBoxAF
.SetPosture( aPosture
);
1050 SvxFontItem
aCJKFont( RES_CHRATR_FONT
);
1051 aCJKFont
.SetFamily( FontFamily::FAMILY_MODERN
);
1052 aCJKFont
.SetPitch( FontPitch::PITCH_FIXED
);
1053 aCJKFont
.SetCharSet( RTL_TEXTENCODING_MS_1251
);
1054 aBoxAF
.SetCJKFont( aCJKFont
);
1056 SvxFontHeightItem
aCJKHeight( 230, 110, RES_CHRATR_FONTSIZE
);
1057 aBoxAF
.SetCJKHeight( aCJKHeight
);
1059 SvxWeightItem
aCJKWeight( FontWeight::WEIGHT_SEMIBOLD
, RES_CHRATR_WEIGHT
);
1060 aBoxAF
.SetCJKWeight( aCJKWeight
);
1062 SvxPostureItem
aCJKPosture( FontItalic::ITALIC_OBLIQUE
, RES_CHRATR_POSTURE
);
1063 aBoxAF
.SetCJKPosture( aCJKPosture
);
1065 SvxFontItem
aCTLFont( RES_CHRATR_FONT
);
1066 aCTLFont
.SetFamily( FontFamily::FAMILY_ROMAN
);
1067 aCTLFont
.SetPitch( FontPitch::PITCH_FIXED
);
1068 aCTLFont
.SetCharSet( RTL_TEXTENCODING_MS_1251
);
1069 aBoxAF
.SetCTLFont( aCTLFont
);
1071 SvxFontHeightItem
aCTLHeight( 215, 105, RES_CHRATR_FONTSIZE
);
1072 aBoxAF
.SetCTLHeight( aCTLHeight
);
1074 SvxWeightItem
aCTLWeight( FontWeight::WEIGHT_ULTRABOLD
, RES_CHRATR_WEIGHT
);
1075 aBoxAF
.SetCTLWeight( aCTLWeight
);
1077 SvxPostureItem
aCTLPosture( FontItalic::ITALIC_OBLIQUE
, RES_CHRATR_POSTURE
);
1078 aBoxAF
.SetCTLPosture( aCTLPosture
);
1080 SvxUnderlineItem
aUnderline( FontLineStyle::LINESTYLE_DOTTED
, RES_CHRATR_UNDERLINE
);
1081 aBoxAF
.SetUnderline( aUnderline
);
1083 SvxOverlineItem
aOverline( FontLineStyle::LINESTYLE_DASH
, RES_CHRATR_OVERLINE
);
1084 aBoxAF
.SetOverline( aOverline
);
1086 SvxCrossedOutItem
aCrossedOut( FontStrikeout::STRIKEOUT_BOLD
, RES_CHRATR_CROSSEDOUT
);
1087 aBoxAF
.SetCrossedOut( aCrossedOut
);
1089 SvxContourItem
aContour( true, RES_CHRATR_CONTOUR
);
1090 aBoxAF
.SetContour( aContour
);
1092 SvxShadowedItem
aShadowed( false, RES_CHRATR_SHADOWED
);
1093 aBoxAF
.SetShadowed( aShadowed
);
1095 SvxColorItem
aColor( Color(0xFF23FF), RES_CHRATR_COLOR
);
1096 aBoxAF
.SetColor( aColor
);
1098 SvxAdjustItem
aAdjust( SvxAdjust::Center
, RES_PARATR_ADJUST
);
1099 aBoxAF
.SetAdjust( aAdjust
);
1100 //SetTextOrientation
1101 SvxFrameDirectionItem
aTOrientation( SvxFrameDirection::Vertical_RL_TB
, RES_FRAMEDIR
);
1102 aBoxAF
.SetTextOrientation( aTOrientation
);
1103 //SetVerticalAlignment
1104 SwFormatVertOrient
aVAlignment( 3, css::text::VertOrientation::CENTER
, css::text::RelOrientation::PAGE_LEFT
);
1105 aBoxAF
.SetVerticalAlignment( aVAlignment
);
1107 SvxBoxItem
aBox( RES_BOX
);
1108 aBox
.SetAllDistances( 5 );
1109 aBoxAF
.SetBox( aBox
);
1111 SvxBrushItem
aBackground( Color(0xFF11FF), RES_BACKGROUND
);
1112 aBoxAF
.SetBackground( aBackground
);
1114 SvxLineItem
aTLBRLine(0); aTLBRLine
.ScaleMetrics( 11,12 );
1115 aBoxAF
.SetTLBR(aTLBRLine
);
1117 SvxLineItem
aBLTRLine(0); aBLTRLine
.ScaleMetrics( 13,14 );
1118 aBoxAF
.SetBLTR(aBLTRLine
);
1120 SvxHorJustifyItem
aHJustify( SvxCellHorJustify::Center
, 0 );
1121 aBoxAF
.SetHorJustify(aHJustify
);
1123 SvxVerJustifyItem
aVJustify( SvxCellVerJustify::Center
, 0 );
1124 aBoxAF
.SetVerJustify(aVJustify
);
1126 SfxBoolItem
aStacked(0, true);
1127 aBoxAF
.SetStacked(aStacked
);
1129 SvxMarginItem
aSvxMarginItem(sal_Int16(4), sal_Int16(2), sal_Int16(3), sal_Int16(3), TypedWhichId
<SvxMarginItem
>(0));
1130 aBoxAF
.SetMargin(aSvxMarginItem
);
1132 SfxBoolItem
aLBreak(0, true);
1133 aBoxAF
.SetLinebreak(aLBreak
);
1134 //Set m_aRotateAngle
1135 SfxInt32Item
aRAngle(sal_Int32(5));
1136 aBoxAF
.SetRotateAngle(aRAngle
);
1138 SvxRotateModeItem
aSvxRotateModeItem(SVX_ROTATE_MODE_CENTER
, TypedWhichId
<SvxRotateModeItem
>(0));
1139 aBoxAF
.SetRotateMode(aSvxRotateModeItem
);
1140 //Set m_sNumFormatString
1141 OUString aNFString
= "UnitTestFormat";
1142 aBoxAF
.SetNumFormatString(aNFString
);
1143 //Set m_eSysLanguage
1144 LanguageType
aSLang( LANGUAGE_ENGLISH_INDIA
);
1145 aBoxAF
.SetSysLanguage(aSLang
);
1146 //Set m_eNumFormatLanguage
1147 LanguageType
aNFLang( LANGUAGE_GERMAN
);
1148 aBoxAF
.SetNumFormatLanguage(aNFLang
);
1149 //Set m_aKeepWithNextPara
1150 SvxFormatKeepItem
aKWNPara( true, 0 );
1151 aTableAF
.SetKeepWithNextPara(aKWNPara
);
1152 //Set m_aRepeatHeading
1153 sal_uInt16 aRHeading
= 3;
1154 aTableAF
.m_aRepeatHeading
= aRHeading
;
1155 //Set m_bLayoutSplit
1156 bool aLSplit
= false;
1157 aTableAF
.m_bLayoutSplit
= aLSplit
;
1159 bool aRSplit
= false;
1160 aTableAF
.m_bRowSplit
= aRSplit
;
1161 //Set m_bCollapsingBorders
1162 bool aCBorders
= false;
1163 aTableAF
.m_bCollapsingBorders
= aCBorders
;
1165 SvxShadowItem
aShadow( 0, nullptr, 103, SvxShadowLocation::BottomLeft
);
1166 aTableAF
.SetShadow(aShadow
);
1168 bool aIFont
= false;
1169 aTableAF
.m_bInclFont
= aIFont
;
1171 bool aIJustify
= false;
1172 aTableAF
.m_bInclJustify
= aIJustify
;
1174 bool aIFrame
= false;
1175 aTableAF
.m_bInclFrame
= aIFrame
;
1176 //Set bInclBackground
1177 bool aIBackground
= false;
1178 aTableAF
.m_bInclBackground
= aIBackground
;
1179 //Set bInclValueFormat
1180 bool aIVFormat
= false;
1181 aTableAF
.m_bInclValueFormat
= aIVFormat
;
1183 //set the box format to AutoFormat
1184 aTableAF
.SetBoxFormat( aBoxAF
, sal_uInt8(0) );
1185 //add AutoFormat to AutoFormatTable
1186 aTableAFT
.AddAutoFormat( aTableAF
);
1188 //check the style size
1189 CPPUNIT_ASSERT_EQUAL( size_t(2), aTableAFT
.size() );
1191 //save the bInclFontstyles
1194 //check the style size after save
1195 CPPUNIT_ASSERT_EQUAL( size_t(2), aTableAFT
.size() );
1197 //create new AutoFormatTable
1198 SwTableAutoFormatTable aLoadTAFT
;
1200 //check the style size
1201 CPPUNIT_ASSERT_EQUAL( size_t(1), aLoadTAFT
.size() );
1203 //load the saved styles
1206 //check the style size after load
1207 CPPUNIT_ASSERT_EQUAL( size_t(2), aLoadTAFT
.size() );
1210 SwTableAutoFormat
* pLoadAF
= aLoadTAFT
.FindAutoFormat( u
"TestItemStyle" );
1211 CPPUNIT_ASSERT( pLoadAF
);
1213 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetFont() == aFont
) );
1215 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetHeight() == aHeight
) );
1217 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetWeight() == aWeight
) );
1219 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetPosture() == aPosture
) );
1221 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetCJKFont() == aCJKFont
) );
1223 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetCJKHeight() == aCJKHeight
) );
1225 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetCJKWeight() == aCJKWeight
) );
1227 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetCJKPosture() == aCJKPosture
) );
1229 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetCTLFont() == aCTLFont
) );
1231 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetCTLHeight() == aCTLHeight
) );
1233 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetCTLWeight() == aCTLWeight
) );
1235 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetCTLPosture() == aCTLPosture
) );
1237 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetUnderline() == aUnderline
) );
1239 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetOverline() == aOverline
) );
1241 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetCrossedOut() == aCrossedOut
) );
1243 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetContour() == aContour
) );
1245 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetShadowed() == aShadowed
) );
1247 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetColor() == aColor
) );
1249 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetAdjust() == aAdjust
) );
1250 //GetTextOrientation
1251 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetTextOrientation() == aTOrientation
) );
1252 //GetVerticalAlignment
1253 CPPUNIT_ASSERT (bool( pLoadAF
->GetBoxFormat(0).GetVerticalAlignment() == aVAlignment
) );
1255 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetBox() == aBox
) );
1257 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetBackground() == aBackground
) );
1259 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetTLBR() == aTLBRLine
) );
1261 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetBLTR() == aBLTRLine
) );
1263 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetHorJustify() == aHJustify
) );
1265 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetVerJustify() == aVJustify
) );
1267 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetStacked() == aStacked
) );
1269 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetMargin() == aSvxMarginItem
) );
1271 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetLinebreak() == aLBreak
) );
1272 //Get m_aRotateAngle
1273 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetRotateAngle() == aRAngle
) );
1275 //SvxRotateModeItem aRMode = aBoxAF.m_aRotateMode;GetRotateMode
1276 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetRotateMode() == aSvxRotateModeItem
) );
1277 //Get m_sNumFormatString
1278 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetNumFormatString() == aNFString
) );
1279 //Get m_eSysLanguage
1280 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetSysLanguage() == aSLang
) );
1281 //Get m_eNumFormatLanguage
1282 CPPUNIT_ASSERT( bool( pLoadAF
->GetBoxFormat(0).GetNumFormatLanguage() == aNFLang
) );
1283 //Get m_aKeepWithNextPara
1284 CPPUNIT_ASSERT( bool( pLoadAF
->GetKeepWithNextPara() == aKWNPara
) );
1285 //Get m_aRepeatHeading
1286 CPPUNIT_ASSERT( bool( pLoadAF
->m_aRepeatHeading
== aRHeading
) );
1287 //Get m_bLayoutSplit
1288 CPPUNIT_ASSERT( bool( pLoadAF
->m_bLayoutSplit
== aLSplit
) );
1290 CPPUNIT_ASSERT( bool( pLoadAF
->m_bRowSplit
== aRSplit
) );
1291 //Get m_bCollapsingBorders
1292 CPPUNIT_ASSERT( bool( pLoadAF
->m_bCollapsingBorders
== aCBorders
) );
1294 CPPUNIT_ASSERT( bool( pLoadAF
->GetShadow() == aShadow
) );
1296 CPPUNIT_ASSERT( bool( pLoadAF
->m_bInclFont
== aIFont
) );
1298 CPPUNIT_ASSERT( bool( pLoadAF
->m_bInclJustify
== aIJustify
) );
1300 CPPUNIT_ASSERT( bool( pLoadAF
->m_bInclFrame
== aIFrame
) );
1301 //Get bInclBackground
1302 CPPUNIT_ASSERT( bool( pLoadAF
->m_bInclBackground
== aIBackground
) );
1303 //Get bInclValueFormat
1304 CPPUNIT_ASSERT( bool( pLoadAF
->m_bInclValueFormat
== aIVFormat
) );
1308 translitTest(SwDoc
& rDoc
, const SwPaM
& rPaM
, TransliterationFlags
const nType
)
1310 utl::TransliterationWrapper
aTrans(
1311 ::comphelper::getProcessComponentContext(), nType
);
1312 rDoc
.getIDocumentContentOperations().TransliterateText(rPaM
, aTrans
);
1313 return rPaM
.GetText();
1316 void SwDocTest::testTransliterate()
1318 // just some simple test to see if it's totally broken
1319 SwNodeIndex
aIdx(m_pDoc
->GetNodes().GetEndOfContent(), -1);
1321 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "foobar");
1323 aPaM
.GetPoint()->nContent
= 0;
1324 CPPUNIT_ASSERT_EQUAL(OUString("foobar"), aPaM
.GetText());
1326 CPPUNIT_ASSERT_EQUAL(OUString("FOOBAR"),
1327 translitTest(*m_pDoc
, aPaM
,
1328 TransliterationFlags::LOWERCASE_UPPERCASE
));
1329 CPPUNIT_ASSERT_EQUAL(OUString("Foobar"),
1330 translitTest(*m_pDoc
, aPaM
,
1331 TransliterationFlags::TITLE_CASE
));
1332 CPPUNIT_ASSERT_EQUAL(OUString("fOOBAR"),
1333 translitTest(*m_pDoc
, aPaM
,
1334 TransliterationFlags::TOGGLE_CASE
));
1335 CPPUNIT_ASSERT_EQUAL(OUString("foobar"),
1336 translitTest(*m_pDoc
, aPaM
,
1337 TransliterationFlags::UPPERCASE_LOWERCASE
));
1338 CPPUNIT_ASSERT_EQUAL(OUString("Foobar"),
1339 translitTest(*m_pDoc
, aPaM
,
1340 TransliterationFlags::SENTENCE_CASE
));
1341 CPPUNIT_ASSERT_EQUAL(OUString("Foobar"),
1342 translitTest(*m_pDoc
, aPaM
,
1343 TransliterationFlags::HIRAGANA_KATAKANA
));
1345 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
1346 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "one (two) three");
1348 aPaM
.GetMark()->nContent
= 0;
1349 CPPUNIT_ASSERT_EQUAL(OUString("One (Two) Three"),
1350 translitTest(*m_pDoc
, aPaM
,
1351 TransliterationFlags::TITLE_CASE
));
1356 class SwTableFormulaTest
: public SwTableFormula
1358 SwTableNode
*m_pNode
;
1360 SwTableFormulaTest(const OUString
&rStr
, SwTableNode
*pNode
)
1361 : SwTableFormula(rStr
)
1364 m_eNmType
= INTRNL_NAME
;
1366 virtual const SwNode
* GetNodeOfFormula() const override
1373 //tdf#66353 Expression is faulty
1374 void SwDocTest::testFormulas()
1376 SwNodeIndex
aIdx(m_pDoc
->GetNodes().GetEndOfContent(), -1);
1377 SwPosition
aPos(aIdx
);
1379 const SwTable
*pTable
= m_pDoc
->InsertTable(
1380 SwInsertTableOptions(SwInsertTableFlags::HeadlineNoBorder
, 0), aPos
, 1, 3, 0);
1381 SwTableNode
* pTableNode
= pTable
->GetTableNode();
1382 SwTableFormulaTest
aFormula("<\x12-1,0>+<Table1.A1>", pTableNode
);
1384 aFormula
.PtrToBoxNm(pTable
);
1386 CPPUNIT_ASSERT_EQUAL(OUString("<?>+<Table1.?>"), aFormula
.GetFormula());
1388 // tdf#61228: Evaluating non-defined function should return an error
1389 SwCalc
aCalc(*m_pDoc
);
1390 SwSbxValue val
= aCalc
.Calculate("foobar()");
1391 CPPUNIT_ASSERT(aCalc
.IsCalcError());
1392 CPPUNIT_ASSERT(val
.IsVoidValue());
1393 CPPUNIT_ASSERT(val
.IsDouble());
1394 CPPUNIT_ASSERT_EQUAL(DBL_MAX
, val
.GetDouble());
1395 // Evaluating non-defined variable should return 0 without an error
1396 val
= aCalc
.Calculate("foobar");
1397 CPPUNIT_ASSERT(!aCalc
.IsCalcError());
1398 CPPUNIT_ASSERT(val
.IsVoidValue());
1399 CPPUNIT_ASSERT(val
.IsLong());
1400 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), val
.GetLong());
1403 void SwDocTest::testMarkMove()
1405 IDocumentMarkAccess
* pMarksAccess
= m_pDoc
->getIDocumentMarkAccess();
1408 SwNodeIndex
aIdx(m_pDoc
->GetNodes().GetEndOfContent(), -1);
1410 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "Paragraph 1");
1412 aPaM
.GetMark()->nContent
-= aPaM
.GetMark()->GetContentIndex();
1413 pMarksAccess
->makeMark(aPaM
, "Para1",
1414 IDocumentMarkAccess::MarkType::BOOKMARK
, sw::mark::InsertMode::New
);
1416 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
1417 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "Paragraph 2");
1419 aPaM
.GetMark()->nContent
-= aPaM
.GetMark()->GetContentIndex();
1420 pMarksAccess
->makeMark(aPaM
, "Para2",
1421 IDocumentMarkAccess::MarkType::BOOKMARK
, sw::mark::InsertMode::New
);
1423 m_pDoc
->getIDocumentContentOperations().AppendTextNode(*aPaM
.GetPoint());
1424 m_pDoc
->getIDocumentContentOperations().InsertString(aPaM
, "Paragraph 3");
1426 aPaM
.GetMark()->nContent
-= aPaM
.GetMark()->GetContentIndex();
1427 pMarksAccess
->makeMark(aPaM
, "Para3",
1428 IDocumentMarkAccess::MarkType::BOOKMARK
, sw::mark::InsertMode::New
);
1431 // join paragraph 2 and 3 and check
1433 SwNodeIndex
aIdx(m_pDoc
->GetNodes().GetEndOfContent(), -2);
1434 SwTextNode
& rParaNode2
= dynamic_cast<SwTextNode
&>(aIdx
.GetNode());
1435 rParaNode2
.JoinNext();
1437 ::sw::mark::IMark
* pBM1
= *pMarksAccess
->findMark("Para1");
1438 ::sw::mark::IMark
* pBM2
= *pMarksAccess
->findMark("Para2");
1439 ::sw::mark::IMark
* pBM3
= *pMarksAccess
->findMark("Para3");
1441 CPPUNIT_ASSERT_EQUAL(sal_Int32(0) , pBM1
->GetMarkStart().GetContentIndex());
1442 CPPUNIT_ASSERT_EQUAL(sal_Int32(11), pBM1
->GetMarkEnd().GetContentIndex());
1443 CPPUNIT_ASSERT_EQUAL(
1444 pBM1
->GetMarkStart().GetNodeIndex(),
1445 pBM1
->GetMarkEnd().GetNodeIndex());
1447 CPPUNIT_ASSERT_EQUAL(sal_Int32(0) , pBM2
->GetMarkStart().GetContentIndex());
1448 CPPUNIT_ASSERT_EQUAL(sal_Int32(11), pBM2
->GetMarkEnd().GetContentIndex());
1449 CPPUNIT_ASSERT_EQUAL(
1450 pBM2
->GetMarkStart().GetNodeIndex(),
1451 pBM2
->GetMarkEnd().GetNodeIndex());
1453 CPPUNIT_ASSERT_EQUAL(sal_Int32(11), pBM3
->GetMarkStart().GetContentIndex());
1454 CPPUNIT_ASSERT_EQUAL(sal_Int32(22), pBM3
->GetMarkEnd().GetContentIndex());
1455 CPPUNIT_ASSERT_EQUAL(
1456 pBM3
->GetMarkStart().GetNodeIndex(),
1457 pBM3
->GetMarkEnd().GetNodeIndex());
1459 CPPUNIT_ASSERT_EQUAL(
1460 pBM1
->GetMarkStart().GetNodeIndex()+1,
1461 pBM2
->GetMarkStart().GetNodeIndex());
1462 CPPUNIT_ASSERT_EQUAL(
1463 pBM2
->GetMarkStart().GetNodeIndex(),
1464 pBM3
->GetMarkStart().GetNodeIndex());
1468 SwNodeIndex
aIdx(m_pDoc
->GetNodes().GetEndOfContent(), -1);
1469 SwPaM
aPaM(aIdx
, aIdx
, SwNodeOffset(-1));
1470 aPaM
.GetPoint()->nContent
+= 5;
1471 aPaM
.GetMark()->nContent
+= 6;
1472 m_pDoc
->getIDocumentContentOperations().DeleteAndJoin(aPaM
);
1474 pBM1
= *pMarksAccess
->findMark("Para1");
1475 pBM2
= *pMarksAccess
->findMark("Para2");
1476 pBM3
= *pMarksAccess
->findMark("Para3");
1478 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pBM1
->GetMarkStart().GetContentIndex());
1479 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pBM1
->GetMarkEnd().GetContentIndex());
1480 CPPUNIT_ASSERT_EQUAL(
1481 pBM1
->GetMarkStart().GetNodeIndex(),
1482 pBM1
->GetMarkEnd().GetNodeIndex());
1484 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pBM2
->GetMarkStart().GetContentIndex());
1485 CPPUNIT_ASSERT_EQUAL(sal_Int32(12), pBM2
->GetMarkEnd().GetContentIndex());
1486 CPPUNIT_ASSERT_EQUAL(
1487 pBM2
->GetMarkStart().GetNodeIndex(),
1488 pBM2
->GetMarkEnd().GetNodeIndex());
1490 CPPUNIT_ASSERT_EQUAL(sal_Int32(12), pBM3
->GetMarkStart().GetContentIndex());
1491 CPPUNIT_ASSERT_EQUAL(sal_Int32(23), pBM3
->GetMarkEnd().GetContentIndex());
1492 CPPUNIT_ASSERT_EQUAL(
1493 pBM3
->GetMarkStart().GetNodeIndex(),
1494 pBM3
->GetMarkEnd().GetNodeIndex());
1496 CPPUNIT_ASSERT_EQUAL(
1497 pBM1
->GetMarkStart().GetNodeIndex(),
1498 pBM2
->GetMarkStart().GetNodeIndex());
1499 CPPUNIT_ASSERT_EQUAL(
1500 pBM2
->GetMarkStart().GetNodeIndex(),
1501 pBM3
->GetMarkStart().GetNodeIndex());
1503 // split the paragraph
1505 SwNodeIndex
aIdx(m_pDoc
->GetNodes().GetEndOfContent(), -1);
1506 SwPosition
aPos(aIdx
);
1508 m_pDoc
->getIDocumentContentOperations().SplitNode(aPos
, false);
1510 pBM1
= *pMarksAccess
->findMark("Para1");
1511 pBM2
= *pMarksAccess
->findMark("Para2");
1512 pBM3
= *pMarksAccess
->findMark("Para3");
1514 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pBM1
->GetMarkStart().GetContentIndex());
1515 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pBM1
->GetMarkEnd().GetContentIndex());
1516 CPPUNIT_ASSERT_EQUAL(
1517 pBM1
->GetMarkStart().GetNodeIndex(),
1518 pBM1
->GetMarkEnd().GetNodeIndex());
1520 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pBM2
->GetMarkStart().GetContentIndex());
1521 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pBM2
->GetMarkEnd().GetContentIndex());
1522 CPPUNIT_ASSERT_EQUAL(
1523 pBM2
->GetMarkStart().GetNodeIndex()+1,
1524 pBM2
->GetMarkEnd().GetNodeIndex());
1526 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pBM3
->GetMarkStart().GetContentIndex());
1527 CPPUNIT_ASSERT_EQUAL(sal_Int32(15), pBM3
->GetMarkEnd().GetContentIndex());
1528 CPPUNIT_ASSERT_EQUAL(
1529 pBM3
->GetMarkStart().GetNodeIndex(),
1530 pBM3
->GetMarkEnd().GetNodeIndex());
1532 CPPUNIT_ASSERT_EQUAL(
1533 pBM1
->GetMarkStart().GetNodeIndex(),
1534 pBM2
->GetMarkStart().GetNodeIndex());
1535 CPPUNIT_ASSERT_EQUAL(
1536 pBM2
->GetMarkEnd().GetNodeIndex(),
1537 pBM3
->GetMarkEnd().GetNodeIndex());
1542 struct TestRing
: public sw::Ring
<TestRing
>
1544 TestRing() : sw::Ring
<TestRing
>() {};
1546 { return GetNextInRing(); }
1548 { return GetPrevInRing(); }
1550 { return unique(); }
1554 void SwDocTest::testIntrusiveRing()
1556 TestRing aRing1
, aRing2
, aRing3
, aRing4
, aRing5
;
1557 std::vector
<TestRing
*> vRings
1565 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aRing1
.GetRingContainer().size());
1566 CPPUNIT_ASSERT(aRing1
.lonely());
1567 CPPUNIT_ASSERT(aRing2
.lonely());
1568 CPPUNIT_ASSERT(aRing3
.lonely());
1569 aRing2
.MoveTo(&aRing1
);
1570 aRing3
.MoveTo(&aRing1
);
1571 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aRing1
.GetRingContainer().size());
1572 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aRing2
.GetRingContainer().size());
1573 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aRing3
.GetRingContainer().size());
1574 CPPUNIT_ASSERT(!aRing1
.lonely());
1575 CPPUNIT_ASSERT(!aRing2
.lonely());
1576 CPPUNIT_ASSERT(!aRing3
.lonely());
1577 aRing5
.MoveTo(&aRing4
);
1578 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aRing4
.GetRingContainer().size());
1579 aRing4
.GetRingContainer().merge(aRing1
.GetRingContainer());
1580 for(TestRing
* pRing
: vRings
)
1582 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(5), pRing
->GetRingContainer().size());
1584 for(std::vector
<TestRing
*>::iterator ppRing
= vRings
.begin(); ppRing
!= vRings
.end(); ++ppRing
)
1586 std::vector
<TestRing
*>::iterator ppNext
= ppRing
+1;
1587 if(ppNext
==vRings
.end())
1588 ppNext
= vRings
.begin();
1589 CPPUNIT_ASSERT_EQUAL((*ppRing
)->GetNext(), *ppNext
);
1590 CPPUNIT_ASSERT_EQUAL((*ppNext
)->GetPrev(), *ppRing
);
1592 for(TestRing
& r
: aRing1
.GetRingContainer())
1594 TestRing
* pRing
= &r
;
1595 CPPUNIT_ASSERT(pRing
);
1597 const TestRing
* pConstRing
= &aRing1
;
1598 for(const TestRing
& r
: pConstRing
->GetRingContainer()) // this should fail without r being const
1600 const TestRing
* pRing
= &r
;
1601 CPPUNIT_ASSERT(pRing
);
1605 CPPUNIT_ASSERT_EQUAL(&foo
, bar
.GetNext());
1606 CPPUNIT_ASSERT_EQUAL(&foo
, bar
.GetPrev());
1607 CPPUNIT_ASSERT_EQUAL(&bar
, foo
.GetNext());
1608 CPPUNIT_ASSERT_EQUAL(&bar
, foo
.GetPrev());
1610 CPPUNIT_ASSERT_EQUAL(&bar
, bar
.GetNext());
1611 CPPUNIT_ASSERT_EQUAL(&bar
, bar
.GetPrev());
1612 CPPUNIT_ASSERT_EQUAL(&foo
, foo
.GetNext());
1613 CPPUNIT_ASSERT_EQUAL(&foo
, foo
.GetPrev());
1618 struct TestHint final
: SfxHint
{};
1619 struct TestModify
: sw::BroadcastingModify
1622 struct TestClient
: SwClient
1626 int m_nModifyChangedCount
;
1627 const SwModify
* m_pLastChangedModify
;
1628 TestClient() : m_nModifyCount(0), m_nNotifyCount(0), m_nModifyChangedCount(0), m_pLastChangedModify(nullptr) {};
1629 virtual void SwClientNotify(const SwModify
&, const SfxHint
& rHint
) override
1631 if(typeid(TestHint
) == typeid(rHint
))
1633 else if(dynamic_cast<const sw::LegacyModifyHint
*>(&rHint
))
1635 else if(auto pModifyChangedHint
= dynamic_cast<const sw::ModifyChangedHint
*>(&rHint
))
1637 ++m_nModifyChangedCount
;
1638 m_pLastChangedModify
= pModifyChangedHint
->m_pNew
;
1642 struct OtherTestClient
: SwClient
1645 OtherTestClient() : m_nModifyCount(0) {};
1646 virtual void SwClientNotify(const SwModify
&, const SfxHint
& rHint
) override
1648 if(dynamic_cast<const sw::LegacyModifyHint
*>(&rHint
))
1652 struct TestListener
: SvtListener
1655 TestListener() : m_nNotifyCount(0) {};
1656 virtual void Notify( const SfxHint
& ) override
1662 void SwDocTest::testClientModify()
1664 (void) OtherTestClient(); // avoid loplugin:unreffun
1666 TestClient aClient1
, aClient2
;
1667 OtherTestClient aOtherClient1
;
1668 // test client registration
1669 CPPUNIT_ASSERT(!aMod
.HasWriterListeners());
1670 CPPUNIT_ASSERT(!aMod
.HasOnlyOneListener());
1671 CPPUNIT_ASSERT_EQUAL(static_cast<SwModify
*>(nullptr),aClient1
.GetRegisteredIn());
1672 CPPUNIT_ASSERT_EQUAL(static_cast<SwModify
*>(nullptr),aClient2
.GetRegisteredIn());
1673 CPPUNIT_ASSERT_EQUAL(static_cast<SwModify
*>(nullptr),aClient2
.GetRegisteredIn());
1674 aMod
.Add(&aClient1
);
1675 CPPUNIT_ASSERT(aMod
.HasWriterListeners());
1676 CPPUNIT_ASSERT(aMod
.HasOnlyOneListener());
1677 aMod
.Add(&aClient2
);
1678 CPPUNIT_ASSERT_EQUAL(static_cast<SwModify
*>(&aMod
),aClient1
.GetRegisteredIn());
1679 CPPUNIT_ASSERT_EQUAL(static_cast<SwModify
*>(&aMod
), aClient2
.GetRegisteredIn());
1680 CPPUNIT_ASSERT(aMod
.HasWriterListeners());
1681 CPPUNIT_ASSERT(!aMod
.HasOnlyOneListener());
1683 aMod
.CallSwClientNotify(sw::LegacyModifyHint(nullptr, nullptr));
1684 CPPUNIT_ASSERT_EQUAL(1,aClient1
.m_nModifyCount
);
1685 CPPUNIT_ASSERT_EQUAL(1,aClient2
.m_nModifyCount
);
1686 CPPUNIT_ASSERT_EQUAL(0,aClient1
.m_nNotifyCount
);
1687 CPPUNIT_ASSERT_EQUAL(0,aClient2
.m_nNotifyCount
);
1688 aMod
.CallSwClientNotify(sw::LegacyModifyHint(nullptr, nullptr));
1689 CPPUNIT_ASSERT_EQUAL(2,aClient1
.m_nModifyCount
);
1690 CPPUNIT_ASSERT_EQUAL(2,aClient2
.m_nModifyCount
);
1691 CPPUNIT_ASSERT_EQUAL(0,aClient1
.m_nNotifyCount
);
1692 CPPUNIT_ASSERT_EQUAL(0,aClient2
.m_nNotifyCount
);
1696 aMod
.CallSwClientNotify(aHint
);
1697 CPPUNIT_ASSERT_EQUAL(2,aClient1
.m_nModifyCount
);
1698 CPPUNIT_ASSERT_EQUAL(2,aClient2
.m_nModifyCount
);
1699 CPPUNIT_ASSERT_EQUAL(1,aClient1
.m_nNotifyCount
);
1700 CPPUNIT_ASSERT_EQUAL(1,aClient2
.m_nNotifyCount
);
1702 // test typed iteration
1703 CPPUNIT_ASSERT(typeid(aClient1
) != typeid(OtherTestClient
));
1705 SwIterator
<OtherTestClient
,SwModify
> aIter(aMod
);
1706 for(OtherTestClient
* pClient
= aIter
.First(); pClient
; pClient
= aIter
.Next())
1707 CPPUNIT_ASSERT(false);
1711 SwIterator
<TestClient
,SwModify
> aIter(aMod
);
1712 for(TestClient
* pClient
= aIter
.First(); pClient
; pClient
= aIter
.Next())
1714 CPPUNIT_ASSERT_EQUAL(2,pClient
->m_nModifyCount
);
1717 CPPUNIT_ASSERT_EQUAL(2,nCount
);
1719 aMod
.Add(&aOtherClient1
);
1720 CPPUNIT_ASSERT_EQUAL(0,aOtherClient1
.m_nModifyCount
);
1723 SwIterator
<TestClient
,SwModify
> aIter(aMod
);
1724 for(TestClient
* pClient
= aIter
.First(); pClient
; pClient
= aIter
.Next())
1726 CPPUNIT_ASSERT_EQUAL(2,pClient
->m_nModifyCount
);
1729 CPPUNIT_ASSERT_EQUAL(2,nCount
);
1731 CPPUNIT_ASSERT_EQUAL(0,aOtherClient1
.m_nModifyCount
);
1732 aMod
.Remove(&aOtherClient1
);
1733 CPPUNIT_ASSERT_EQUAL(static_cast<SwModify
*>(&aMod
),aClient1
.GetRegisteredIn());
1734 CPPUNIT_ASSERT_EQUAL(static_cast<SwModify
*>(&aMod
),aClient2
.GetRegisteredIn());
1735 CPPUNIT_ASSERT_EQUAL(static_cast<SwModify
*>(nullptr),aOtherClient1
.GetRegisteredIn());
1736 // test client self-deregistration during iteration
1739 SwIterator
<TestClient
,SwModify
> aIter(aMod
);
1740 for(TestClient
* pClient
= aIter
.First(); pClient
; pClient
= aIter
.Next())
1742 aMod
.Remove(pClient
);
1745 CPPUNIT_ASSERT_EQUAL(2,nCount
);
1747 CPPUNIT_ASSERT_EQUAL(static_cast<SwModify
*>(nullptr),aClient1
.GetRegisteredIn());
1748 CPPUNIT_ASSERT_EQUAL(static_cast<SwModify
*>(nullptr),aClient2
.GetRegisteredIn());
1750 SwIterator
<TestClient
,SwModify
> aIter(aMod
);
1751 for(TestClient
* pClient
= aIter
.First(); pClient
; pClient
= aIter
.Next())
1753 CPPUNIT_ASSERT(false);
1756 aMod
.CallSwClientNotify(sw::LegacyModifyHint(nullptr, nullptr));
1757 CPPUNIT_ASSERT_EQUAL(2,aClient1
.m_nModifyCount
);
1758 CPPUNIT_ASSERT_EQUAL(2,aClient2
.m_nModifyCount
);
1759 CPPUNIT_ASSERT_EQUAL(1,aClient1
.m_nNotifyCount
);
1760 CPPUNIT_ASSERT_EQUAL(1,aClient2
.m_nNotifyCount
);
1762 void SwDocTest::testBroadcastingModify()
1764 sw::BroadcastingModify aMod
;
1766 TestListener aListener
;
1769 aListener
.StartListening(aMod
.GetNotifier());
1771 aMod
.CallSwClientNotify(sw::LegacyModifyHint(nullptr, nullptr));
1772 CPPUNIT_ASSERT_EQUAL(1,aClient
.m_nModifyCount
);
1773 CPPUNIT_ASSERT_EQUAL(1,aClient
.m_nModifyCount
);
1774 CPPUNIT_ASSERT_EQUAL(1,aListener
.m_nNotifyCount
);
1776 void SwDocTest::testWriterMultiListener()
1780 sw::WriterMultiListener
aMulti(aClient
);
1781 CPPUNIT_ASSERT(!aMulti
.IsListeningTo(&aMod
));
1782 aMulti
.StartListening(&aMod
);
1783 CPPUNIT_ASSERT(aMulti
.IsListeningTo(&aMod
));
1784 aMulti
.EndListeningAll();
1785 CPPUNIT_ASSERT(!aMulti
.IsListeningTo(&aMod
));
1786 aMulti
.StartListening(&aMod
);
1787 aMulti
.EndListening(&aMod
);
1788 CPPUNIT_ASSERT(!aMulti
.IsListeningTo(&aMod
));
1789 int nPreDeathChangedCount
;
1791 TestModify aTempMod
;
1792 aMod
.Add(&aTempMod
);
1793 aMulti
.StartListening(&aTempMod
);
1794 nPreDeathChangedCount
= aClient
.m_nModifyChangedCount
;
1796 CPPUNIT_ASSERT(aMulti
.IsListeningTo(&aMod
));
1797 CPPUNIT_ASSERT_EQUAL(nPreDeathChangedCount
+1, aClient
.m_nModifyChangedCount
);
1798 CPPUNIT_ASSERT_EQUAL(static_cast<const SwModify
*>(&aMod
),aClient
.m_pLastChangedModify
);
1801 void SwDocTest::test64kPageDescs()
1803 size_t nPageDescCount
= 65536; // USHRT_MAX + 1
1805 for (size_t i
= 0; i
< nPageDescCount
; ++i
)
1807 OUString aName
= "Page" + OUString::number(i
);
1808 m_pDoc
->MakePageDesc( aName
);
1811 size_t nCount
= m_pDoc
->GetPageDescCnt();
1812 // +1 because Writer always creates a dummy page desc
1814 CPPUNIT_ASSERT_EQUAL( nPageDescCount
+ 1, nCount
);
1816 const SwPageDesc
&rDesc
= m_pDoc
->GetPageDesc( nPageDescCount
);
1817 SwPageDesc
&rZeroDesc
= m_pDoc
->GetPageDesc( 0 );
1818 CPPUNIT_ASSERT_EQUAL( OUString("Page65535"), rDesc
.GetName() );
1820 SwPageDesc
aDesc( rDesc
);
1821 static const OUStringLiteral
aChanged(u
"Changed01");
1822 aDesc
.SetName( aChanged
);
1823 m_pDoc
->ChgPageDesc( nPageDescCount
, aDesc
);
1826 SwPageDesc
*pDesc
= m_pDoc
->FindPageDesc( aChanged
, &nPos
);
1827 CPPUNIT_ASSERT( pDesc
!= nullptr );
1828 CPPUNIT_ASSERT_EQUAL( nPageDescCount
, nPos
);
1830 // check if we didn't mess up PageDesc at pos 0
1831 // (happens with 16bit int overflow)
1832 OUString aZeroName
= rZeroDesc
.GetName();
1833 rZeroDesc
= m_pDoc
->GetPageDesc( 0 );
1834 CPPUNIT_ASSERT_EQUAL( aZeroName
, rZeroDesc
.GetName() );
1836 m_pDoc
->DelPageDesc( aChanged
, /*bBroadcast*/true );
1837 pDesc
= m_pDoc
->FindPageDesc( aChanged
, &nPos
);
1838 // not there anymore
1839 CPPUNIT_ASSERT( !pDesc
);
1840 CPPUNIT_ASSERT_EQUAL( std::numeric_limits
<size_t>::max(), nPos
);
1842 // check if PageDesc at pos 0 is still there
1843 pDesc
= m_pDoc
->FindPageDesc( aZeroName
, &nPos
);
1844 CPPUNIT_ASSERT( pDesc
!= nullptr );
1845 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(0), nPos
);
1848 void SwDocTest::testTdf92308()
1850 CPPUNIT_ASSERT_EQUAL(false, m_pDoc
->HasInvisibleContent());
1853 void SwDocTest::testTableCellComparison()
1855 CPPUNIT_ASSERT_EQUAL( -1, sw_CompareCellsByColFirst(u
"A1", u
"Z1") );
1856 CPPUNIT_ASSERT_EQUAL( +1, sw_CompareCellsByColFirst(u
"Z1", u
"A1") );
1857 CPPUNIT_ASSERT_EQUAL( 0, sw_CompareCellsByColFirst(u
"A1", u
"A1") );
1859 CPPUNIT_ASSERT_EQUAL( +1, sw_CompareCellsByColFirst(u
"A2", u
"A1") );
1860 CPPUNIT_ASSERT_EQUAL( +1, sw_CompareCellsByColFirst(u
"Z3", u
"A2") );
1861 CPPUNIT_ASSERT_EQUAL( -1, sw_CompareCellsByColFirst(u
"A3", u
"Z1") );
1863 CPPUNIT_ASSERT_EQUAL( -1, sw_CompareCellsByRowFirst(u
"A1", u
"Z1") );
1864 CPPUNIT_ASSERT_EQUAL( +1, sw_CompareCellsByRowFirst(u
"Z1", u
"A1") );
1865 CPPUNIT_ASSERT_EQUAL( 0, sw_CompareCellsByRowFirst(u
"A1", u
"A1") );
1867 CPPUNIT_ASSERT_EQUAL( +1, sw_CompareCellsByRowFirst(u
"A2", u
"A1") );
1868 CPPUNIT_ASSERT_EQUAL( +1, sw_CompareCellsByRowFirst(u
"Z3", u
"A2") );
1869 CPPUNIT_ASSERT_EQUAL( +1, sw_CompareCellsByRowFirst(u
"A3", u
"Z1") );
1871 CPPUNIT_ASSERT_EQUAL( 0, sw_CompareCellRanges(u
"A1", u
"A1", u
"A1", u
"A1", true) );
1872 CPPUNIT_ASSERT_EQUAL( 0, sw_CompareCellRanges(u
"A1", u
"Z1", u
"A1", u
"Z1", true) );
1873 CPPUNIT_ASSERT_EQUAL( 0, sw_CompareCellRanges(u
"A1", u
"Z1", u
"A1", u
"Z1", false) );
1875 CPPUNIT_ASSERT_EQUAL( -1, sw_CompareCellRanges(u
"A1", u
"Z1", u
"B1", u
"Z1", true) );
1876 CPPUNIT_ASSERT_EQUAL( -1, sw_CompareCellRanges(u
"A1", u
"Z1", u
"A2", u
"Z2", false) );
1877 CPPUNIT_ASSERT_EQUAL( -1, sw_CompareCellRanges(u
"A1", u
"Z1", u
"A2", u
"Z2", true) );
1878 CPPUNIT_ASSERT_EQUAL( -1, sw_CompareCellRanges(u
"A1", u
"Z1", u
"A6", u
"Z2", true) );
1880 CPPUNIT_ASSERT_EQUAL( +1, sw_CompareCellRanges(u
"B1", u
"Z1", u
"A1", u
"Z1", true) );
1881 CPPUNIT_ASSERT_EQUAL( +1, sw_CompareCellRanges(u
"A2", u
"Z2", u
"A1", u
"Z1", false) );
1882 CPPUNIT_ASSERT_EQUAL( +1, sw_CompareCellRanges(u
"A2", u
"Z2", u
"A1", u
"Z1", true) );
1883 CPPUNIT_ASSERT_EQUAL( +1, sw_CompareCellRanges(u
"A6", u
"Z2", u
"A1", u
"Z1", true) );
1885 OUString
rCell1("A1");
1886 OUString
rCell2("C5");
1888 sw_NormalizeRange(rCell1
, rCell2
);
1889 CPPUNIT_ASSERT_EQUAL( OUString("A1"), rCell1
);
1890 CPPUNIT_ASSERT_EQUAL( OUString("C5"), rCell2
);
1892 sw_NormalizeRange(rCell2
, rCell1
);
1893 CPPUNIT_ASSERT_EQUAL( OUString("C5"), rCell1
);
1894 CPPUNIT_ASSERT_EQUAL( OUString("A1"), rCell2
);
1896 rCell1
= OUString("A5");
1897 rCell2
= OUString("C1");
1899 sw_NormalizeRange(rCell1
, rCell2
);
1900 CPPUNIT_ASSERT_EQUAL( OUString("A1"), rCell1
);
1901 CPPUNIT_ASSERT_EQUAL( OUString("C5"), rCell2
);
1903 sw_NormalizeRange(rCell2
, rCell1
);
1904 CPPUNIT_ASSERT_EQUAL( OUString("C5"), rCell1
);
1905 CPPUNIT_ASSERT_EQUAL( OUString("A1"), rCell2
);
1907 CPPUNIT_ASSERT_EQUAL( OUString(), sw_GetCellName(-1, -1) );
1910 void SwDocTest::setUp()
1912 BootstrapFixture::setUp();
1914 SwGlobals::ensure();
1916 m_xDocShRef
= new SwDocShell(*m_pDoc
, SfxObjectCreateMode::EMBEDDED
);
1917 m_xDocShRef
->DoInitNew();
1920 void SwDocTest::tearDown()
1922 m_pDoc
= nullptr; // deleted by DoClose()
1923 m_xDocShRef
->DoClose();
1924 m_xDocShRef
.clear();
1926 BootstrapFixture::tearDown();
1929 CPPUNIT_TEST_SUITE_REGISTRATION(SwDocTest
);
1931 CPPUNIT_PLUGIN_IMPLEMENT();
1933 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */