LCOV - code coverage report
Current view: top level - sw/qa/core - uwriter.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 718 720 99.7 %
Date: 2014-11-03 Functions: 42 43 97.7 %
Legend: Lines: hit not hit

          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 <sal/config.h>
      11             : #include <test/bootstrapfixture.hxx>
      12             : 
      13             : #include <rtl/strbuf.hxx>
      14             : #include <osl/file.hxx>
      15             : 
      16             : #include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
      17             : 
      18             : #include <comphelper/processfactory.hxx>
      19             : #include <comphelper/random.hxx>
      20             : #include <tools/urlobj.hxx>
      21             : #include <unotools/tempfile.hxx>
      22             : #include <unotools/transliterationwrapper.hxx>
      23             : 
      24             : #include <editeng/langitem.hxx>
      25             : #include <editeng/charhiddenitem.hxx>
      26             : 
      27             : #include <sfx2/app.hxx>
      28             : #include <sfx2/docfilt.hxx>
      29             : #include <sfx2/docfile.hxx>
      30             : #include <sfx2/sfxmodelfactory.hxx>
      31             : 
      32             : #include <xmloff/odffields.hxx>
      33             : 
      34             : #include "breakit.hxx"
      35             : #include "doc.hxx"
      36             : #include <IDocumentRedlineAccess.hxx>
      37             : #include <IDocumentFieldsAccess.hxx>
      38             : #include <IDocumentStatistics.hxx>
      39             : #include "docsh.hxx"
      40             : #include "docstat.hxx"
      41             : #include "docufld.hxx"
      42             : #include "fmtanchr.hxx"
      43             : #include "init.hxx"
      44             : #include "ndtxt.hxx"
      45             : #include "shellio.hxx"
      46             : #include "shellres.hxx"
      47             : #include "swcrsr.hxx"
      48             : #include "swscanner.hxx"
      49             : #include "swmodule.hxx"
      50             : #include <swdll.hxx>
      51             : #include "swtypes.hxx"
      52             : #include "fmtftn.hxx"
      53             : #include "fmtrfmrk.hxx"
      54             : #include "fmtfld.hxx"
      55             : #include "redline.hxx"
      56             : #include "docary.hxx"
      57             : #include "modeltoviewhelper.hxx"
      58             : #include "scriptinfo.hxx"
      59             : #include "IMark.hxx"
      60             : 
      61             : typedef tools::SvRef<SwDocShell> SwDocShellRef;
      62             : 
      63             : using namespace ::com::sun::star;
      64             : 
      65             : /* Implementation of Swdoc-Test class */
      66             : 
      67         100 : class SwDocTest : public test::BootstrapFixture
      68             : {
      69             : public:
      70          50 :     SwDocTest()
      71          50 :         : m_pDoc(NULL)
      72             :     {
      73          50 :     }
      74             : 
      75             :     virtual void setUp() SAL_OVERRIDE;
      76             :     virtual void tearDown() SAL_OVERRIDE;
      77             : 
      78             :     void randomTest();
      79             :     void testPageDescName();
      80             :     void testFileNameFields();
      81             :     void testDocStat();
      82             :     void testModelToViewHelperPassthrough();
      83             :     void testModelToViewHelperExpandFieldsExpandFootnote();
      84             :     void testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode();
      85             :     void testModelToViewHelperExpandFields();
      86             :     void testModelToViewHelperExpandFieldsReplaceMode();
      87             :     void testModelToViewHelperExpandFieldsHideInvisible();
      88             :     void testModelToViewHelperExpandFieldsHideRedlined();
      89             :     void testModelToViewHelperExpandFieldsHideInvisibleExpandFootnote();
      90             :     void testModelToViewHelperExpandFieldsHideInvisibleExpandFootnoteReplaceMode();
      91             :     void testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnote();
      92             :     void testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnoteReplaceMode();
      93             :     void testModelToViewHelperHideInvisibleHideRedlined();
      94             :     void testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnote();
      95             :     void testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnoteReplaceMode();
      96             :     void testModelToViewHelperExpandFieldsExpandFootnote2();
      97             :     void testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode2();
      98             :     void testSwScanner();
      99             :     void testUserPerceivedCharCount();
     100             :     void testGraphicAnchorDeletion();
     101             :     void testTransliterate();
     102             :     void testMarkMove();
     103             : 
     104           4 :     CPPUNIT_TEST_SUITE(SwDocTest);
     105           2 :     CPPUNIT_TEST(testTransliterate);
     106           2 :     CPPUNIT_TEST(randomTest);
     107           2 :     CPPUNIT_TEST(testPageDescName);
     108           2 :     CPPUNIT_TEST(testFileNameFields);
     109           2 :     CPPUNIT_TEST(testDocStat);
     110           2 :     CPPUNIT_TEST(testModelToViewHelperPassthrough);
     111           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsExpandFootnote);
     112           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode);
     113           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFields);
     114           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsReplaceMode);
     115           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideInvisible);
     116           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideRedlined);
     117           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideInvisibleExpandFootnote);
     118           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideInvisibleExpandFootnoteReplaceMode);
     119           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnote);
     120           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnoteReplaceMode);
     121           2 :     CPPUNIT_TEST(testModelToViewHelperHideInvisibleHideRedlined);
     122           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnote);
     123           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnoteReplaceMode);
     124           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsExpandFootnote2);
     125           2 :     CPPUNIT_TEST(testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode2);
     126           2 :     CPPUNIT_TEST(testSwScanner);
     127           2 :     CPPUNIT_TEST(testUserPerceivedCharCount);
     128           2 :     CPPUNIT_TEST(testGraphicAnchorDeletion);
     129           2 :     CPPUNIT_TEST(testMarkMove);
     130           4 :     CPPUNIT_TEST_SUITE_END();
     131             : 
     132             : private:
     133             :     SwDoc *m_pDoc;
     134             :     SwDocShellRef m_xDocShRef;
     135             : };
     136             : 
     137           2 : void SwDocTest::testPageDescName()
     138             : {
     139           2 :     ShellResource aShellResources;
     140             : 
     141           4 :     std::vector<OUString> aResults;
     142             : 
     143             :     //These names must be unique for each different combination, otherwise
     144             :     //duplicate page description names may exist, which will causes lookup
     145             :     //by name to be incorrect, and so the corresponding export to .odt
     146           2 :     aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::NORMAL_PAGE));
     147           2 :     aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::FIRST_PAGE));
     148           2 :     aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::FOLLOW_PAGE));
     149             : 
     150           2 :     std::sort(aResults.begin(), aResults.end());
     151           2 :     aResults.erase(std::unique(aResults.begin(), aResults.end()), aResults.end());
     152             : 
     153           4 :     CPPUNIT_ASSERT_MESSAGE("GetPageDescName results must be unique", aResults.size() == 3);
     154           2 : }
     155             : 
     156             : //See https://bugs.libreoffice.org/show_bug.cgi?id=32463
     157           2 : void SwDocTest::testFileNameFields()
     158             : {
     159             :     //Here's a file name with some chars in it that will be %% encoded, when expanding
     160             :     //SwFileNameFields we want to restore the original readable filename
     161           2 :     utl::TempFile aTempFile(OUString("demo [name]"));
     162           2 :     aTempFile.EnableKillingFile();
     163             : 
     164           4 :     INetURLObject aTempFileURL(aTempFile.GetURL());
     165           4 :     OUString sFileURL = aTempFileURL.GetMainURL(INetURLObject::NO_DECODE);
     166           4 :     SfxMedium aDstMed(sFileURL, STREAM_STD_READWRITE);
     167             : 
     168             :     SfxFilter aFilter(
     169             :         OUString("Text"),
     170             :         OUString(), 0, 0, OUString(), 0, OUString(),
     171           4 :         OUString("TEXT"), OUString() );
     172           2 :     aDstMed.SetFilter(&aFilter);
     173             : 
     174           2 :     m_xDocShRef->DoSaveAs(aDstMed);
     175           2 :     m_xDocShRef->DoSaveCompleted(&aDstMed);
     176             : 
     177           2 :     const INetURLObject &rUrlObj = m_xDocShRef->GetMedium()->GetURLObject();
     178             : 
     179           4 :     SwFileNameFieldType aNameField(m_pDoc);
     180             : 
     181             :     {
     182           2 :         OUString sResult(aNameField.Expand(FF_NAME));
     183             :         OUString sExpected(rUrlObj.getName(INetURLObject::LAST_SEGMENT,
     184           4 :             true,INetURLObject::DECODE_WITH_CHARSET));
     185           4 :         CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected);
     186             :     }
     187             : 
     188             :     {
     189           2 :         OUString sResult(aNameField.Expand(FF_PATHNAME));
     190           4 :         OUString sExpected(rUrlObj.GetFull());
     191           4 :         CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected);
     192             :     }
     193             : 
     194             :     {
     195           2 :         OUString sResult(aNameField.Expand(FF_PATH));
     196           4 :         INetURLObject aTemp(rUrlObj);
     197           2 :         aTemp.removeSegment();
     198           4 :         OUString sExpected(aTemp.PathToFileName());
     199           4 :         CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected);
     200             :     }
     201             : 
     202             :     {
     203           2 :         OUString sResult(aNameField.Expand(FF_NAME_NOEXT));
     204             :         OUString sExpected(rUrlObj.getName(INetURLObject::LAST_SEGMENT,
     205           4 :             true,INetURLObject::DECODE_WITH_CHARSET));
     206             :         //Chop off .tmp
     207           2 :         sExpected = sExpected.copy(0, sExpected.getLength() - 4);
     208           4 :         CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected);
     209             :     }
     210             : 
     211           4 :     m_xDocShRef->DoInitNew(0);
     212           2 : }
     213             : 
     214             : //See http://lists.freedesktop.org/archives/libreoffice/2011-August/016666.html
     215             : //Remove unnecessary parameter to IDocumentStatistics::UpdateDocStat for
     216             : //motivation
     217           2 : void SwDocTest::testDocStat()
     218             : {
     219           2 :     CPPUNIT_ASSERT_MESSAGE("Expected initial 0 count", m_pDoc->getIDocumentStatistics().GetDocStat().nChar == 0);
     220             : 
     221           2 :     SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
     222           4 :     SwPaM aPaM(aIdx);
     223             : 
     224           4 :     OUString sText("Hello World");
     225           2 :     m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sText);
     226             : 
     227           2 :     CPPUNIT_ASSERT_MESSAGE("Should still be non-updated 0 count", m_pDoc->getIDocumentStatistics().GetDocStat().nChar == 0);
     228             : 
     229           2 :     SwDocStat aDocStat = m_pDoc->getIDocumentStatistics().GetUpdatedDocStat( false, true );
     230           2 :     sal_uLong nLen = static_cast<sal_uLong>(sText.getLength());
     231             : 
     232           2 :     CPPUNIT_ASSERT_MESSAGE("Should now have updated count", aDocStat.nChar == nLen);
     233             : 
     234           4 :     CPPUNIT_ASSERT_MESSAGE("And cache is updated too", m_pDoc->getIDocumentStatistics().GetDocStat().nChar == nLen);
     235           2 : }
     236             : 
     237             : //For UI character counts we should follow UAX#29 and display the user
     238             : //perceived characters, not the number of codepoints, nor the number of code
     239             : //units http://unicode.org/reports/tr29/
     240           2 : void SwDocTest::testUserPerceivedCharCount()
     241             : {
     242           2 :     SwBreakIt *pBreakIter = SwBreakIt::Get();
     243             : 
     244             :     //Grapheme example, two different unicode code-points perceived by the user as a single
     245             :     //glyph
     246           2 :     const sal_Unicode ALEF_QAMATS [] = { 0x05D0, 0x05B8 };
     247           2 :     OUString sALEF_QAMATS(ALEF_QAMATS, SAL_N_ELEMENTS(ALEF_QAMATS));
     248           2 :     sal_Int32 nGraphemeCount = pBreakIter->getGraphemeCount(sALEF_QAMATS);
     249           2 :     CPPUNIT_ASSERT_MESSAGE("Grapheme Count should be 1", nGraphemeCount == 1);
     250             : 
     251             :     //Surrogate pair example, one single unicode code-point (U+1D11E)
     252             :     //represented as two code units in UTF-16
     253           2 :     const sal_Unicode GCLEF[] = { 0xD834, 0xDD1E };
     254           4 :     OUString sGCLEF(GCLEF, SAL_N_ELEMENTS(GCLEF));
     255           2 :     sal_Int32 nCount = pBreakIter->getGraphemeCount(sGCLEF);
     256           4 :     CPPUNIT_ASSERT_MESSAGE("Surrogate Pair should be counted as single character", nCount == 1);
     257           2 : }
     258             : 
     259          32 : SwTxtNode* getModelToViewTestDocument(SwDoc *pDoc)
     260             : {
     261          32 :     SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
     262          64 :     SwPaM aPaM(aIdx);
     263             : 
     264          64 :     SwFmtFtn aFtn;
     265          32 :     aFtn.SetNumStr(OUString("foo"));
     266             : 
     267          32 :     pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     268          32 :     pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("AAAAA BBBBB "));
     269          32 :     SwTxtNode* pTxtNode = aPaM.GetNode().GetTxtNode();
     270          32 :     sal_Int32 nPos = aPaM.GetPoint()->nContent.GetIndex();
     271          32 :     pTxtNode->InsertItem(aFtn, nPos, nPos);
     272          32 :     pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(" CCCCC "));
     273          32 :     nPos = aPaM.GetPoint()->nContent.GetIndex();
     274          32 :     pTxtNode->InsertItem(aFtn, nPos, nPos);
     275          32 :     pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(" DDDDD"));
     276          32 :     CPPUNIT_ASSERT(pTxtNode->GetTxt().getLength() == (4*5) + 5 + 2);
     277             : 
     278             :     //set start of selection to first B
     279          32 :     aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 6);
     280          32 :     aPaM.SetMark();
     281             :     //set end of selection to last C
     282          32 :     aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 14);
     283             :     //set character attribute hidden on range
     284          64 :     SvxCharHiddenItem aHidden(true, RES_CHRATR_HIDDEN);
     285          32 :     pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, aHidden, 0 );
     286          32 :     aPaM.DeleteMark();
     287             : 
     288             :     //turn on red-lining and show changes
     289          32 :     pDoc->getIDocumentRedlineAccess().SetRedlineMode(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE|nsRedlineMode_t::REDLINE_SHOW_INSERT);
     290          32 :     CPPUNIT_ASSERT_MESSAGE("redlining should be on", pDoc->getIDocumentRedlineAccess().IsRedlineOn());
     291          32 :     CPPUNIT_ASSERT_MESSAGE("redlines should be visible", IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineMode()));
     292             : 
     293             :     //set start of selection to last A
     294          32 :     aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 4);
     295          32 :     aPaM.SetMark();
     296             :     //set end of selection to second last B
     297          32 :     aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 9);
     298          32 :     pDoc->getIDocumentContentOperations().DeleteAndJoin(aPaM);    //redline-aware deletion api
     299          32 :     aPaM.DeleteMark();
     300             : 
     301          64 :     return pTxtNode;
     302             : }
     303             : 
     304           4 : SwTxtNode* getModelToViewTestDocument2(SwDoc *pDoc)
     305             : {
     306           4 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(pDoc);
     307             : 
     308           4 :     SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
     309           8 :     SwPaM aPaM(aIdx);
     310             : 
     311           4 :     pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     312           4 :     pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("AAAAA"));
     313           4 :     IDocumentMarkAccess* pMarksAccess = pDoc->getIDocumentMarkAccess();
     314             :     sw::mark::IFieldmark *pFieldmark = dynamic_cast<sw::mark::IFieldmark*>(
     315           4 :             pMarksAccess->makeNoTextFieldBookmark(aPaM, "test", ODF_FORMDROPDOWN));
     316           4 :     CPPUNIT_ASSERT(pFieldmark);
     317           8 :     uno::Sequence< OUString > vListEntries(1);
     318           4 :     vListEntries[0] = "BBBBB";
     319           4 :     (*pFieldmark->GetParameters())[ODF_FORMDROPDOWN_LISTENTRY] = uno::makeAny(vListEntries);
     320           4 :     (*pFieldmark->GetParameters())[ODF_FORMDROPDOWN_RESULT] = uno::makeAny(sal_Int32(0));
     321           4 :     pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("CCCCC"));
     322           4 :     pTxtNode = aPaM.GetNode().GetTxtNode();
     323           8 :     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(11),
     324           4 :             pTxtNode->GetTxt().getLength());
     325             : 
     326           8 :     return pTxtNode;
     327             : }
     328             : 
     329           2 : void SwDocTest::testModelToViewHelperPassthrough()
     330             : {
     331           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     332             : 
     333           2 :     ModelToViewHelper aModelToViewHelper(*pTxtNode, PASSTHROUGH);
     334           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     335           4 :     OUString sModelText = pTxtNode->GetTxt();
     336           4 :     CPPUNIT_ASSERT_EQUAL(sModelText, sViewText);
     337           2 : }
     338             : 
     339           2 : void SwDocTest::testModelToViewHelperExpandFieldsExpandFootnote()
     340             : {
     341           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     342             : 
     343           2 :     ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | EXPANDFOOTNOTE);
     344           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     345           4 :     CPPUNIT_ASSERT_EQUAL(
     346           4 :         OUString("AAAAA BBBBB foo CCCCC foo DDDDD"), sViewText);
     347           2 : }
     348             : 
     349           2 : void SwDocTest::testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode()
     350             : {
     351           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     352             : 
     353             :     ModelToViewHelper aModelToViewHelper(*pTxtNode,
     354           2 :             EXPANDFIELDS | EXPANDFOOTNOTE | REPLACEMODE);
     355           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     356           4 :     CPPUNIT_ASSERT_EQUAL(
     357             :         OUString("AAAAA BBBBB " + OUString(CHAR_ZWSP) + " CCCCC " + OUString(CHAR_ZWSP) + " DDDDD"),
     358           2 :         sViewText);
     359           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2),
     360           2 :         aModelToViewHelper.getFootnotePositions().size());
     361           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(12),
     362           2 :         aModelToViewHelper.getFootnotePositions()[0]);
     363           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(20),
     364           2 :         aModelToViewHelper.getFootnotePositions()[1]);
     365           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
     366           4 :         aModelToViewHelper.getFieldPositions().size());
     367           2 : }
     368             : 
     369           2 : void SwDocTest::testModelToViewHelperExpandFields()
     370             : {
     371           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     372             : 
     373           2 :     ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS);
     374           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     375           4 :     CPPUNIT_ASSERT_EQUAL(
     376           4 :         OUString("AAAAA BBBBB  CCCCC  DDDDD"), sViewText);
     377           2 : }
     378             : 
     379           2 : void SwDocTest::testModelToViewHelperExpandFieldsReplaceMode()
     380             : {
     381           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     382             : 
     383             :     ModelToViewHelper aModelToViewHelper(*pTxtNode,
     384           2 :         EXPANDFIELDS | REPLACEMODE);
     385           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     386           4 :     CPPUNIT_ASSERT_EQUAL(OUString("AAAAA BBBBB  CCCCC  DDDDD"),
     387           2 :         sViewText);
     388           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
     389           2 :         aModelToViewHelper.getFootnotePositions().size());
     390           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
     391           4 :         aModelToViewHelper.getFieldPositions().size());
     392           2 : }
     393             : 
     394           2 : void SwDocTest::testModelToViewHelperExpandFieldsHideInvisible()
     395             : {
     396           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     397             : 
     398           2 :     ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEINVISIBLE);
     399           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     400           4 :     CPPUNIT_ASSERT_EQUAL(
     401             :         OUString("AAAAA CCCCC " + OUString(CH_TXTATR_BREAKWORD) + " DDDDD"),
     402           4 :         sViewText);
     403           2 : }
     404             : 
     405           2 : void SwDocTest::testModelToViewHelperExpandFieldsHideRedlined()
     406             : {
     407           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     408             : 
     409           2 :     ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEREDLINED);
     410           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     411           4 :     CPPUNIT_ASSERT_EQUAL(
     412             :         OUString("AAAABB " + OUString(CH_TXTATR_BREAKWORD) + " CCCCC " + OUString(CH_TXTATR_BREAKWORD) + " DDDDD"),
     413           4 :         sViewText);
     414           2 : }
     415             : 
     416           2 : void SwDocTest::testModelToViewHelperExpandFieldsHideInvisibleExpandFootnote()
     417             : {
     418           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     419             : 
     420           2 :     ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEINVISIBLE | EXPANDFOOTNOTE);
     421           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     422           4 :     CPPUNIT_ASSERT_EQUAL(OUString("AAAAA CCCCC foo DDDDD"), sViewText);
     423           2 : }
     424             : 
     425           2 : void SwDocTest::testModelToViewHelperExpandFieldsHideInvisibleExpandFootnoteReplaceMode()
     426             : {
     427           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     428             : 
     429             :     ModelToViewHelper aModelToViewHelper(*pTxtNode,
     430           2 :         EXPANDFIELDS | HIDEINVISIBLE | EXPANDFOOTNOTE | REPLACEMODE);
     431           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     432           4 :     CPPUNIT_ASSERT_EQUAL(
     433             :         OUString("AAAAA CCCCC " + OUString(CHAR_ZWSP) + " DDDDD"),
     434           2 :         sViewText);
     435           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1),
     436           2 :         aModelToViewHelper.getFootnotePositions().size());
     437           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(12),
     438           2 :         aModelToViewHelper.getFootnotePositions()[0]);
     439           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
     440           4 :         aModelToViewHelper.getFieldPositions().size());
     441           2 : }
     442             : 
     443           2 : void SwDocTest::testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnote()
     444             : {
     445           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     446             : 
     447           2 :     ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEREDLINED | EXPANDFOOTNOTE);
     448           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     449           4 :     CPPUNIT_ASSERT_EQUAL(
     450           4 :         OUString("AAAABB foo CCCCC foo DDDDD"), sViewText);
     451           2 : }
     452             : 
     453           2 : void SwDocTest::testModelToViewHelperExpandFieldsHideHideRedlinedExpandFootnoteReplaceMode()
     454             : {
     455           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     456             : 
     457             :     ModelToViewHelper aModelToViewHelper(*pTxtNode,
     458           2 :         EXPANDFIELDS | HIDEREDLINED | EXPANDFOOTNOTE | REPLACEMODE);
     459           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     460           4 :     CPPUNIT_ASSERT_EQUAL(
     461             :        OUString("AAAABB " + OUString(CHAR_ZWSP) + " CCCCC " + OUString(CHAR_ZWSP) + " DDDDD"),
     462           2 :        sViewText);
     463           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2),
     464           2 :         aModelToViewHelper.getFootnotePositions().size());
     465           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(7),
     466           2 :         aModelToViewHelper.getFootnotePositions()[0]);
     467           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(15),
     468           2 :         aModelToViewHelper.getFootnotePositions()[1]);
     469           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
     470           4 :         aModelToViewHelper.getFieldPositions().size());
     471           2 : }
     472             : 
     473           2 : void SwDocTest::testModelToViewHelperHideInvisibleHideRedlined()
     474             : {
     475           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     476             : 
     477           2 :     ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEINVISIBLE | HIDEREDLINED);
     478           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     479           4 :     OUStringBuffer aBuffer;
     480           2 :     aBuffer.append("AAAACCCCC ");
     481           2 :     aBuffer.append(CH_TXTATR_BREAKWORD);
     482           2 :     aBuffer.append(" DDDDD");
     483           4 :     CPPUNIT_ASSERT_EQUAL(aBuffer.makeStringAndClear(), sViewText);
     484           2 : }
     485             : 
     486           2 : void SwDocTest::testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnote()
     487             : {
     488           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     489             : 
     490           2 :     ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEINVISIBLE | HIDEREDLINED | EXPANDFOOTNOTE);
     491           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     492           4 :     CPPUNIT_ASSERT_EQUAL(OUString("AAAACCCCC foo DDDDD"), sViewText);
     493           2 : }
     494             : 
     495           2 : void SwDocTest::testModelToViewHelperExpandFieldsHideInvisibleHideRedlinedExpandFootnoteReplaceMode()
     496             : {
     497           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument(m_pDoc);
     498             : 
     499             :     ModelToViewHelper aModelToViewHelper(*pTxtNode,
     500           2 :         EXPANDFIELDS | HIDEINVISIBLE | HIDEREDLINED | EXPANDFOOTNOTE | REPLACEMODE);
     501           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     502           4 :     CPPUNIT_ASSERT_EQUAL(sViewText,
     503           2 :         OUString("AAAACCCCC " + OUString(CHAR_ZWSP) + " DDDDD"));
     504           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1),
     505           2 :         aModelToViewHelper.getFootnotePositions().size());
     506           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(10),
     507           2 :         aModelToViewHelper.getFootnotePositions()[0]);
     508           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
     509           4 :         aModelToViewHelper.getFieldPositions().size());
     510           2 : }
     511             : 
     512           2 : void SwDocTest::testModelToViewHelperExpandFieldsExpandFootnote2()
     513             : {
     514           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument2(m_pDoc);
     515             : 
     516           2 :     ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | EXPANDFOOTNOTE);
     517           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     518           4 :     CPPUNIT_ASSERT_EQUAL(OUString("AAAAABBBBBCCCCC"), sViewText);
     519           2 : }
     520             : 
     521           2 : void SwDocTest::testModelToViewHelperExpandFieldsExpandFootnoteReplaceMode2()
     522             : {
     523           2 :     SwTxtNode* pTxtNode = getModelToViewTestDocument2(m_pDoc);
     524             : 
     525             :     ModelToViewHelper aModelToViewHelper(*pTxtNode,
     526           2 :         EXPANDFIELDS | EXPANDFOOTNOTE | REPLACEMODE);
     527           4 :     OUString sViewText = aModelToViewHelper.getViewText();
     528           4 :     CPPUNIT_ASSERT_EQUAL(
     529             :         OUString("AAAAA" + OUString(CHAR_ZWSP) + "CCCCC"),
     530           2 :         sViewText);
     531           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0),
     532           2 :         aModelToViewHelper.getFootnotePositions().size());
     533           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1),
     534           2 :         aModelToViewHelper.getFieldPositions().size());
     535           4 :     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5),
     536           4 :         aModelToViewHelper.getFieldPositions()[0]);
     537           2 : }
     538             : 
     539           2 : void SwDocTest::testSwScanner()
     540             : {
     541           2 :     SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
     542           4 :     SwPaM aPaM(aIdx);
     543             : 
     544           2 :     SwTxtNode* pTxtNode = aPaM.GetNode().GetTxtNode();
     545             : 
     546           2 :     CPPUNIT_ASSERT_MESSAGE("Has Text Node", pTxtNode);
     547             : 
     548             :     //See https://bugs.libreoffice.org/show_bug.cgi?id=40449
     549             :     //See https://bugs.libreoffice.org/show_bug.cgi?id=39365
     550             :     //Use a temporary OUString as the arg, as that's the trouble behind
     551             :     //fdo#40449 and fdo#39365
     552             :     {
     553             :         SwScanner aScanner(*pTxtNode,
     554             :             OUString("Hello World"),
     555             :             0, ModelToViewHelper(), i18n::WordType::DICTIONARY_WORD, 0,
     556           2 :             RTL_CONSTASCII_LENGTH("Hello World"));
     557             : 
     558           2 :         bool bFirstOk = aScanner.NextWord();
     559           2 :         CPPUNIT_ASSERT_MESSAGE("First Token", bFirstOk);
     560           2 :         const OUString &rHello = aScanner.GetWord();
     561           4 :         CPPUNIT_ASSERT_MESSAGE("Should be Hello",
     562           2 :             rHello == "Hello");
     563             : 
     564           2 :         bool bSecondOk = aScanner.NextWord();
     565           2 :         CPPUNIT_ASSERT_MESSAGE("Second Token", bSecondOk);
     566           2 :         const OUString &rWorld = aScanner.GetWord();
     567           4 :         CPPUNIT_ASSERT_MESSAGE("Should be World",
     568           4 :             rWorld == "World");
     569             :     }
     570             : 
     571             :     //See https://www.libreoffice.org/bugzilla/show_bug.cgi?id=45271
     572             :     {
     573           2 :         const sal_Unicode IDEOGRAPHICFULLSTOP_D[] = { 0x3002, 'D' };
     574             : 
     575           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(IDEOGRAPHICFULLSTOP_D,
     576           2 :             SAL_N_ELEMENTS(IDEOGRAPHICFULLSTOP_D)));
     577             : 
     578           2 :         SvxLanguageItem aCJKLangItem( LANGUAGE_CHINESE_SIMPLIFIED, RES_CHRATR_CJK_LANGUAGE );
     579           4 :         SvxLanguageItem aWestLangItem( LANGUAGE_ENGLISH_US, RES_CHRATR_LANGUAGE );
     580           2 :         m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, aCJKLangItem, 0 );
     581           2 :         m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, aWestLangItem, 0 );
     582             : 
     583           2 :         SwDocStat aDocStat;
     584           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     585           2 :         pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(IDEOGRAPHICFULLSTOP_D));
     586             : 
     587           2 :         CPPUNIT_ASSERT_MESSAGE("Should be 2", aDocStat.nChar == 2);
     588           4 :         CPPUNIT_ASSERT_MESSAGE("Should be 2", aDocStat.nCharExcludingSpaces == 2);
     589             :     }
     590             :     {
     591             :         const sal_Unicode test[] =
     592             :         {
     593             :             0x3053, 0x306E, 0x65E5, 0x672C, 0x8A9E, 0x306F, 0x6B63, 0x3057,
     594             :             0x304F, 0x6570, 0x3048, 0x3089, 0x308C, 0x308B, 0x3067, 0x3057,
     595             :             0x3087, 0x3046, 0x304B, 0x3002, 0x0041, 0x006E, 0x0064, 0x0020,
     596             :             0x006C, 0x0065, 0x0074, 0x0027, 0x0073, 0x0020, 0x0074, 0x0068,
     597             :             0x0072, 0x006F, 0x0077, 0x0020, 0x0073, 0x006F, 0x006D, 0x0065,
     598             :             0x0020, 0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068,
     599             :             0x0020, 0x0069, 0x006E, 0x0020, 0x0074, 0x006F, 0x0020, 0x006D,
     600             :             0x0061, 0x006B, 0x0065, 0x0020, 0x0069, 0x0074, 0x0020, 0x0069,
     601             :             0x006E, 0x0074, 0x0065, 0x0072, 0x0065, 0x0073, 0x0074, 0x0069,
     602             :             0x006E, 0x0067, 0x002E, 0x0020, 0x0020, 0x305D, 0x3057, 0x3066,
     603             :             0x3001, 0x307E, 0x305F, 0x65E5, 0x672C, 0x8A9E, 0x3000, 0x3000,
     604             :             0x3067, 0x3082, 0x4ECA, 0x56DE, 0x306F, 0x7A7A, 0x767D, 0x3092,
     605             :             0x3000, 0x3000, 0x5165, 0x308C, 0x307E, 0x3057, 0x305F, 0x3002,
     606             :             0x0020, 0x0020, 0x0053, 0x006F, 0x0020, 0x0068, 0x006F, 0x0077,
     607             :             0x0020, 0x0064, 0x006F, 0x0065, 0x0073, 0x0020, 0x0074, 0x0068,
     608             :             0x0069, 0x0073, 0x0020, 0x0064, 0x006F, 0x003F, 0x0020, 0x0020
     609           2 :         };
     610           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     611           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(test,
     612           2 :             SAL_N_ELEMENTS(test)));
     613             : 
     614           2 :         SvxLanguageItem aCJKLangItem( LANGUAGE_JAPANESE, RES_CHRATR_CJK_LANGUAGE );
     615           4 :         SvxLanguageItem aWestLangItem( LANGUAGE_ENGLISH_US, RES_CHRATR_LANGUAGE );
     616           2 :         m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, aCJKLangItem, 0 );
     617           2 :         m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, aWestLangItem, 0 );
     618             : 
     619           2 :         SwDocStat aDocStat;
     620           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     621           2 :         pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(test));
     622           2 :         CPPUNIT_ASSERT_MESSAGE("58 words", aDocStat.nWord == 58);
     623           2 :         CPPUNIT_ASSERT_MESSAGE("43 Asian characters and Korean syllables", aDocStat.nAsianWord == 43);
     624           2 :         CPPUNIT_ASSERT_MESSAGE("105 non-whitespace chars", aDocStat.nCharExcludingSpaces == 105);
     625           4 :         CPPUNIT_ASSERT_MESSAGE("128 characters", aDocStat.nChar == 128);
     626             :     }
     627             : 
     628             :     //See https://issues.apache.org/ooo/show_bug.cgi?id=89042
     629             :     //See https://bugs.libreoffice.org/show_bug.cgi?id=53399
     630             :     {
     631           2 :         SwDocStat aDocStat;
     632             : 
     633             :         const sal_Unicode aShouldBeThree[] = {
     634             :             0x0053, 0x0068, 0x006F, 0x0075, 0x006C, 0x0064, 0x0020,
     635             :             0x2018, 0x0062, 0x0065, 0x0020, 0x0074, 0x0068, 0x0072,
     636             :             0x0065, 0x0065, 0x2019
     637           2 :         };
     638             : 
     639           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     640           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(aShouldBeThree, SAL_N_ELEMENTS(aShouldBeThree)));
     641           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     642           2 :         pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(aShouldBeThree));
     643           2 :         CPPUNIT_ASSERT_MESSAGE("Should be 3", aDocStat.nWord == 3);
     644             : 
     645             :         const sal_Unicode aShouldBeFive[] = {
     646             :             // f    r       e       n       c       h       space
     647             :             0x0046, 0x0072, 0x0065, 0x006E, 0x0063, 0x0068, 0x0020,
     648             :             // <<   nbsp    s       a       v       o       i
     649             :             0x00AB, 0x00A0, 0x0073, 0x0061, 0x0076, 0x006F, 0x0069,
     650             :             // r    nnbsp   c       a       l       c       u
     651             :             0x0072, 0x202f, 0x0063, 0x0061, 0x006C, 0x0063, 0x0075,
     652             :             // l    e       r       idspace >>
     653             :             0x006C, 0x0065, 0x0072, 0x3000, 0x00BB
     654           2 :         };
     655             : 
     656           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     657           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(aShouldBeFive, SAL_N_ELEMENTS(aShouldBeFive)));
     658           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     659           2 :         aDocStat.Reset();
     660           2 :         pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(aShouldBeFive));
     661           2 :         CPPUNIT_ASSERT_MESSAGE("Should be 5", aDocStat.nWord == 5);
     662             :     }
     663             : 
     664             :     //See https://bugs.libreoffice.org/show_bug.cgi?id=49629
     665             :     {
     666           2 :         SwDocStat aDocStat;
     667             : 
     668           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     669           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Apple"));
     670           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     671           2 :         sal_Int32 nPos = aPaM.GetPoint()->nContent.GetIndex();
     672           2 :         SwFmtFtn aFtn;
     673           2 :         aFtn.SetNumStr(OUString("banana"));
     674           2 :         SwTxtAttr* pTA = pTxtNode->InsertItem(aFtn, nPos, nPos);
     675           2 :         CPPUNIT_ASSERT(pTA);
     676           2 :         CPPUNIT_ASSERT(pTxtNode->Len() == 6); //Apple + 0x02
     677           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     678           2 :         CPPUNIT_ASSERT(aDocStat.nWord == 1);
     679           2 :         CPPUNIT_ASSERT_MESSAGE("footnote should be expanded", aDocStat.nChar == 11);
     680             : 
     681           2 :         const sal_Int32 nNextPos = aPaM.GetPoint()->nContent.GetIndex();
     682           2 :         CPPUNIT_ASSERT(nNextPos == nPos+1);
     683           4 :         SwFmtRefMark aRef(OUString("refmark"));
     684           2 :         pTA = pTxtNode->InsertItem(aRef, nNextPos, nNextPos);
     685           2 :         CPPUNIT_ASSERT(pTA);
     686             : 
     687           2 :         aDocStat.Reset();
     688           2 :         pTxtNode->SetWordCountDirty(true);
     689           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     690           2 :         CPPUNIT_ASSERT(aDocStat.nWord == 1);
     691           2 :         CPPUNIT_ASSERT_MESSAGE("refmark anchor should not be counted", aDocStat.nChar == 11);
     692             : 
     693           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     694           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Apple"));
     695             : 
     696           2 :         DateTime aDate(DateTime::SYSTEM);
     697             :         SwPostItField aPostIt(
     698           2 :             (SwPostItFieldType*)m_pDoc->getIDocumentFieldsAccess().GetSysFldType(RES_POSTITFLD), OUString("An Author"),
     699           6 :             OUString("Some Text"), OUString("Initials"), OUString("Name"), aDate );
     700           2 :         m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, SwFmtFld(aPostIt), 0);
     701             : 
     702           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Apple"));
     703           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     704           2 :         aDocStat.Reset();
     705           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     706           2 :         CPPUNIT_ASSERT(aDocStat.nWord == 1);
     707           2 :         CPPUNIT_ASSERT_MESSAGE("postit anchor should effectively not exist", aDocStat.nChar == 10);
     708           2 :         CPPUNIT_ASSERT(pTxtNode->Len() == 11);
     709             : 
     710           4 :         aDocStat.Reset();
     711             :     }
     712             : 
     713             :     //See https://bugs.libreoffice.org/show_bug.cgi?id=46757
     714             :     {
     715           2 :         SwDocStat aDocStat;
     716             : 
     717           2 :         const char aString[] = "Lorem ipsum";
     718           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     719           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(aString));
     720           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     721           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     722           2 :         CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast<sal_uLong>(2));
     723             : 
     724             :         //turn on red-lining and show changes
     725           2 :         m_pDoc->getIDocumentRedlineAccess().SetRedlineMode(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE|nsRedlineMode_t::REDLINE_SHOW_INSERT);
     726           2 :         CPPUNIT_ASSERT_MESSAGE("redlining should be on", m_pDoc->getIDocumentRedlineAccess().IsRedlineOn());
     727           2 :         CPPUNIT_ASSERT_MESSAGE("redlines should be visible", IDocumentRedlineAccess::IsShowChanges(m_pDoc->getIDocumentRedlineAccess().GetRedlineMode()));
     728             : 
     729             :         //delete everything except the first word
     730           2 :         aPaM.SetMark(); //set start of selection to current pos
     731           2 :         aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 5);   //set end of selection to fifth char of current node
     732           2 :         m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aPaM);    //redline-aware deletion api
     733             :         //"real underlying text should be the same"
     734           2 :         CPPUNIT_ASSERT_EQUAL(pTxtNode->GetTxt(), OUString(aString));
     735             : 
     736           2 :         aDocStat.Reset();
     737           2 :         pTxtNode->SetWordCountDirty(true);
     738           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //but word-counting the text should only count the non-deleted text
     739           2 :         CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast<sal_uLong>(1));
     740             : 
     741           2 :         pTxtNode->SetWordCountDirty(true);
     742             : 
     743             :         //keep red-lining on but hide changes
     744           2 :         m_pDoc->getIDocumentRedlineAccess().SetRedlineMode(nsRedlineMode_t::REDLINE_ON);
     745           2 :         CPPUNIT_ASSERT_MESSAGE("redlining should be still on", m_pDoc->getIDocumentRedlineAccess().IsRedlineOn());
     746           2 :         CPPUNIT_ASSERT_MESSAGE("redlines should be invisible", !IDocumentRedlineAccess::IsShowChanges(m_pDoc->getIDocumentRedlineAccess().GetRedlineMode()));
     747             : 
     748           2 :         aDocStat.Reset();
     749           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //but word-counting the text should only count the non-deleted text
     750           2 :         CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast<sal_uLong>(1));
     751             : 
     752           2 :         OUString sLorem = pTxtNode->GetTxt();
     753           2 :         CPPUNIT_ASSERT(sLorem == "Lorem");
     754             : 
     755           2 :         const SwRedlineTbl& rTbl = m_pDoc->getIDocumentRedlineAccess().GetRedlineTbl();
     756             : 
     757           2 :         SwNodes& rNds = m_pDoc->GetNodes();
     758           2 :         CPPUNIT_ASSERT(rTbl.size() == 1);
     759             : 
     760           2 :         SwNodeIndex* pNodeIdx = rTbl[0]->GetContentIdx();
     761           2 :         CPPUNIT_ASSERT(pNodeIdx);
     762             : 
     763           2 :         pTxtNode = rNds[ pNodeIdx->GetIndex() + 1 ]->GetTxtNode();        //first deleted txtnode
     764           2 :         CPPUNIT_ASSERT(pTxtNode);
     765             : 
     766           4 :         OUString sIpsum = pTxtNode->GetTxt();
     767           2 :         CPPUNIT_ASSERT(sIpsum == " ipsum");
     768             : 
     769           2 :         aDocStat.Reset();
     770           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //word-counting the text should only count the non-deleted text, and this whole chunk should be ignored
     771           2 :         CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast<sal_uLong>(0));
     772           4 :         CPPUNIT_ASSERT_EQUAL(aDocStat.nChar, static_cast<sal_uLong>(0));
     773             :     }
     774             : 
     775             :     //See https://bugs.libreoffice.org/show_bug.cgi?id=38983
     776             :     {
     777           2 :         SwDocStat aDocStat;
     778             : 
     779           2 :         OUString sTemplate("ThisXis a test.");
     780             : 
     781           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     782           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', ' '));
     783           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     784           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     785           4 :         CPPUNIT_ASSERT(aDocStat.nWord == 4 &&
     786             :                        aDocStat.nCharExcludingSpaces == 12 &&
     787           2 :                        aDocStat.nChar == 15);
     788           2 :         aDocStat.Reset();
     789             : 
     790           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     791           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replaceAll(OUString('X'), OUString(" = ")));
     792           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     793           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     794           4 :         CPPUNIT_ASSERT(aDocStat.nWord == 5 &&
     795             :                        aDocStat.nCharExcludingSpaces == 13 &&
     796           2 :                        aDocStat.nChar == 17);
     797           2 :         aDocStat.Reset();
     798             : 
     799           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     800           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replaceAll(OUString('X'), OUString(" _ ")));
     801           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     802           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     803           4 :         CPPUNIT_ASSERT(aDocStat.nWord == 5 &&
     804             :                        aDocStat.nCharExcludingSpaces == 13 &&
     805           2 :                        aDocStat.nChar == 17);
     806           2 :         aDocStat.Reset();
     807             : 
     808           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     809           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replaceAll(OUString('X'), OUString(" -- ")));
     810           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     811           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     812           4 :         CPPUNIT_ASSERT(aDocStat.nWord == 5 &&
     813             :                        aDocStat.nCharExcludingSpaces == 14 &&
     814           2 :                        aDocStat.nChar == 18);
     815           2 :         aDocStat.Reset();
     816             : 
     817           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     818           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', '_'));
     819           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     820           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     821           4 :         CPPUNIT_ASSERT(aDocStat.nWord == 3 &&
     822             :                        aDocStat.nCharExcludingSpaces == 13 &&
     823           2 :                        aDocStat.nChar == 15);
     824           2 :         aDocStat.Reset();
     825             : 
     826           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     827           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', '-'));
     828           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     829           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     830           4 :         CPPUNIT_ASSERT(aDocStat.nWord == 3 &&
     831             :                        aDocStat.nCharExcludingSpaces == 13 &&
     832           2 :                        aDocStat.nChar == 15);
     833           2 :         aDocStat.Reset();
     834             : 
     835           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     836           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', 0x2012));
     837           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     838           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     839           4 :         CPPUNIT_ASSERT(aDocStat.nWord == 3 &&
     840             :                        aDocStat.nCharExcludingSpaces == 13 &&
     841           2 :                        aDocStat.nChar == 15);
     842           2 :         aDocStat.Reset();
     843             : 
     844           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     845           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', 0x2015));
     846           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     847           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     848           4 :         CPPUNIT_ASSERT(aDocStat.nWord == 3 &&
     849             :                        aDocStat.nCharExcludingSpaces == 13 &&
     850           2 :                        aDocStat.nChar == 15);
     851           2 :         aDocStat.Reset();
     852             : 
     853             :         //But default configuration should, msword-alike treak emdash
     854             :         //and endash as word separators for word-counting
     855           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     856           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', 0x2013));
     857           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     858           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     859           4 :         CPPUNIT_ASSERT(aDocStat.nWord == 4 &&
     860             :                        aDocStat.nCharExcludingSpaces == 13 &&
     861           2 :                        aDocStat.nChar == 15);
     862           2 :         aDocStat.Reset();
     863             : 
     864           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     865           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replace('X', 0x2014));
     866           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     867           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     868           4 :         CPPUNIT_ASSERT(aDocStat.nWord == 4 &&
     869             :                        aDocStat.nCharExcludingSpaces == 13 &&
     870           2 :                        aDocStat.nChar == 15);
     871           2 :         aDocStat.Reset();
     872             : 
     873           2 :         const sal_Unicode aChunk[] = {' ', 0x2013, ' '};
     874           4 :         OUString sChunk(aChunk, SAL_N_ELEMENTS(aChunk));
     875           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     876           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, sTemplate.replaceAll(OUString('X'), sChunk));
     877           2 :         pTxtNode = aPaM.GetNode().GetTxtNode();
     878           2 :         pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
     879           4 :         CPPUNIT_ASSERT(aDocStat.nWord == 4 &&
     880             :                        aDocStat.nCharExcludingSpaces == 13 &&
     881           2 :                        aDocStat.nChar == 17);
     882           4 :         aDocStat.Reset();
     883           2 :     }
     884           2 : }
     885             : 
     886             : //See https://bugs.libreoffice.org/show_bug.cgi?id=40599
     887           2 : void SwDocTest::testGraphicAnchorDeletion()
     888             : {
     889           2 :     CPPUNIT_ASSERT_MESSAGE("Expected initial 0 count", m_pDoc->getIDocumentStatistics().GetDocStat().nChar == 0);
     890             : 
     891           2 :     SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
     892           4 :     SwPaM aPaM(aIdx);
     893             : 
     894           2 :     m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Paragraph 1"));
     895           2 :     m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     896             : 
     897           2 :     m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("graphic anchor>><<graphic anchor"));
     898           4 :     SwNodeIndex nPara2 = aPaM.GetPoint()->nNode;
     899           2 :     m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
     900             : 
     901           2 :     m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Paragraph 3"));
     902             : 
     903           2 :     aPaM.GetPoint()->nNode = nPara2;
     904           2 :     aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), RTL_CONSTASCII_LENGTH("graphic anchor>>"));
     905             : 
     906             :     //Insert a graphic at X of >>X<< in paragraph 2
     907           4 :     SfxItemSet aFlySet(m_pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
     908           4 :     SwFmtAnchor aAnchor(FLY_AS_CHAR);
     909           2 :     aAnchor.SetAnchor(aPaM.GetPoint());
     910           2 :     aFlySet.Put(aAnchor);
     911           2 :     SwFlyFrmFmt *pFrame = m_pDoc->getIDocumentContentOperations().Insert(aPaM, OUString(), OUString(), NULL, &aFlySet, NULL, NULL);
     912           2 :     CPPUNIT_ASSERT_MESSAGE("Expected frame", pFrame != NULL);
     913             : 
     914           2 :     CPPUNIT_ASSERT_MESSAGE("Should be 1 graphic", m_pDoc->GetFlyCount(FLYCNTTYPE_GRF) == 1);
     915             : 
     916             :     //Delete >X<
     917           2 :     aPaM.GetPoint()->nNode = nPara2;
     918           4 :     aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(),
     919           6 :         RTL_CONSTASCII_LENGTH("graphic anchor>><")+1);
     920           2 :     aPaM.SetMark();
     921           2 :     aPaM.GetPoint()->nNode = nPara2;
     922           2 :     aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), RTL_CONSTASCII_LENGTH("graphic anchor>"));
     923           2 :     m_pDoc->getIDocumentContentOperations().DeleteRange(aPaM);
     924             : 
     925             : #ifdef DEBUG_AS_HTML
     926             :     {
     927             :         SvFileStream aPasteDebug(OUString("cppunitDEBUG.html"), STREAM_WRITE|STREAM_TRUNC);
     928             :         WriterRef xWrt;
     929             :         GetHTMLWriter( String(), String(), xWrt );
     930             :         SwWriter aDbgWrt( aPasteDebug, *m_pDoc );
     931             :         aDbgWrt.Write( xWrt );
     932             :     }
     933             : #endif
     934             : 
     935           4 :     CPPUNIT_ASSERT_MESSAGE("Should be 0 graphics", m_pDoc->GetFlyCount(FLYCNTTYPE_GRF) == 0);
     936             : 
     937             :     //Now, if instead we swap FLY_AS_CHAR (inline graphic) to FLY_AT_CHAR (anchored to character)
     938             :     //and repeat the above, graphic is *not* deleted, i.e. it belongs to the paragraph, not the
     939             :     //range to which its anchored, which is annoying.
     940           2 : }
     941             : 
     942             : static int
     943       73341 : getRand(int modulus)
     944             : {
     945       73341 :     if (modulus <= 0)
     946           0 :         return 0;
     947       73341 :     return comphelper::rng::uniform_int_distribution(0, modulus-1);
     948             : }
     949             : 
     950             : static OUString
     951        8172 : getRandString()
     952             : {
     953        8172 :     OUString aText("AAAAA BBBB CCC DD E \n");
     954        8172 :     int s = getRand(aText.getLength());
     955        8172 :     int j = getRand(aText.getLength() - s);
     956        8172 :     OUString aRet(aText.copy(s, j));
     957        8172 :     if (!getRand(5))
     958        1631 :         aRet += OUString('\n');
     959             : //    fprintf (stderr, "rand string '%s'\n", OUStringToOString(aRet, RTL_TEXTENCODING_UTF8).getStr());
     960        8172 :     return aRet;
     961             : }
     962             : 
     963             : static SwPosition
     964       37214 : getRandomPosition(SwDoc *pDoc, int /* nOffset */)
     965             : {
     966       37214 :     const SwPosition aPos(pDoc->GetNodes().GetEndOfContent());
     967       37214 :     size_t nNodes = aPos.nNode.GetNode().GetIndex() - aPos.nNode.GetNode().StartOfSectionIndex();
     968       37214 :     size_t n = comphelper::rng::uniform_size_distribution(0, nNodes);
     969       74428 :     SwPaM pam(aPos);
     970       74636 :     for (sal_uLong i = 0; i < n; ++i)
     971             :     {
     972       37422 :         pam.Move(fnMoveBackward, fnGoNode);
     973             :     }
     974       74428 :     return *pam.GetPoint();
     975             : }
     976             : 
     977           2 : void SwDocTest::randomTest()
     978             : {
     979           2 :     CPPUNIT_ASSERT_MESSAGE("SwDoc::IsRedlineOn()", !m_pDoc->getIDocumentRedlineAccess().IsRedlineOn());
     980             :     RedlineMode_t modes[] = {
     981             :         nsRedlineMode_t::REDLINE_ON,
     982             :         nsRedlineMode_t::REDLINE_SHOW_MASK,
     983             :         nsRedlineMode_t::REDLINE_NONE,
     984             :         nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_MASK,
     985             :         nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE,
     986             :         nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE | nsRedlineMode_t::REDLINE_SHOW_MASK,
     987             :         nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT,
     988             :         nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE
     989           2 :     };
     990             :     static const char *authors[] = {
     991             :         "Jim", "Bob", "JimBobina", "Helga", "Gertrude", "Spagna", "Hurtleweed"
     992             :     };
     993             : 
     994          18 :     for( sal_uInt16 rlm = 0; rlm < SAL_N_ELEMENTS(modes); rlm++ )
     995             :     {
     996          16 :         m_pDoc->ClearDoc();
     997             : 
     998             :         // setup redlining
     999          16 :         m_pDoc->getIDocumentRedlineAccess().SetRedlineMode(modes[rlm]);
    1000          16 :         SW_MOD()->SetRedlineAuthor(OUString::createFromAscii(authors[0]));
    1001             : 
    1002       32016 :         for( int i = 0; i < 2000; i++ )
    1003             :         {
    1004       32000 :             SwPaM aPam(m_pDoc->GetNodes());
    1005       64000 :             SwCursor aCrs(getRandomPosition(m_pDoc, i/20), 0, false);
    1006       32000 :             aCrs.SetMark();
    1007             : 
    1008       32000 :             switch (getRand (i < 50 ? 3 : 6)) {
    1009             :             // insert ops first
    1010             :             case 0: {
    1011        5548 :                 if (!m_pDoc->getIDocumentContentOperations().InsertString(aCrs, getRandString())) {
    1012             : //                    fprintf (stderr, "failed to insert string !\n");
    1013             :                 }
    1014        5548 :                 break;
    1015             :             }
    1016             :             case 1:
    1017        5380 :                 break;
    1018             :             case 2: { // switch author
    1019        5504 :                 int a = getRand(SAL_N_ELEMENTS(authors));
    1020        5504 :                 SW_MOD()->SetRedlineAuthor(OUString::createFromAscii(authors[a]));
    1021        5504 :                 break;
    1022             :             }
    1023             : 
    1024             :             // movement / deletion ops later
    1025             :             case 3: // deletion
    1026        5238 :                 switch (getRand(6)) {
    1027             :                 case 0:
    1028         883 :                     m_pDoc->getIDocumentContentOperations().DelFullPara(aCrs);
    1029         883 :                     break;
    1030             :                 case 1:
    1031         862 :                     m_pDoc->getIDocumentContentOperations().DeleteRange(aCrs);
    1032         862 :                     break;
    1033             :                 case 2:
    1034         869 :                     m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aCrs, !!getRand(1));
    1035         869 :                     break;
    1036             :                 case 3:
    1037             :                 default:
    1038        2624 :                     m_pDoc->getIDocumentContentOperations().Overwrite(aCrs, getRandString());
    1039        2624 :                     break;
    1040             :                 }
    1041        5238 :                 break;
    1042             :             case 4: { // movement
    1043             :                 IDocumentContentOperations::SwMoveFlags nFlags =
    1044             :                     (IDocumentContentOperations::SwMoveFlags)
    1045        5214 :                         (getRand(1) ? // FIXME: puterb this more ?
    1046             :                          IDocumentContentOperations::DOC_MOVEDEFAULT :
    1047             :                          IDocumentContentOperations::DOC_MOVEALLFLYS |
    1048             :                          IDocumentContentOperations::DOC_CREATEUNDOOBJ |
    1049             :                          IDocumentContentOperations::DOC_MOVEREDLINES |
    1050        5214 :                          IDocumentContentOperations::DOC_NO_DELFRMS);
    1051        5214 :                 SwPosition aTo(getRandomPosition(m_pDoc, i/10));
    1052        5214 :                 m_pDoc->getIDocumentContentOperations().MoveRange(aCrs, aTo, nFlags);
    1053        5214 :                 break;
    1054             :             }
    1055             : 
    1056             :             case 5:
    1057        5116 :                 break;
    1058             : 
    1059             :             // undo / redo ?
    1060             :             default:
    1061           0 :                 break;
    1062             :             }
    1063       32000 :         }
    1064             : 
    1065             : // Debug / verify the produced document has real content
    1066             : #if 0
    1067             :         OStringBuffer aBuffer("nodes-");
    1068             :         aBuffer.append(sal_Int32(rlm));
    1069             :         aBuffer.append(".xml");
    1070             : 
    1071             :         xmlTextWriterPtr writer;
    1072             :         writer = xmlNewTextWriterFilename( aBuffer.makeStringAndClear().getStr(), 0 );
    1073             :         xmlTextWriterStartDocument( writer, NULL, NULL, NULL );
    1074             :         m_pDoc->dumpAsXml(writer);
    1075             :         xmlTextWriterEndDocument( writer );
    1076             :         xmlFreeTextWriter( writer );
    1077             : #endif
    1078             :     }
    1079           2 : }
    1080             : 
    1081             : static OUString
    1082          12 : translitTest(SwDoc & rDoc, SwPaM & rPaM, sal_uInt32 const nType)
    1083             : {
    1084             :     utl::TransliterationWrapper aTrans(
    1085          12 :             ::comphelper::getProcessComponentContext(), nType);
    1086          12 :     rDoc.getIDocumentContentOperations().TransliterateText(rPaM, aTrans);
    1087          12 :     return rPaM.GetTxt();
    1088             : }
    1089             : 
    1090           2 : void SwDocTest::testTransliterate()
    1091             : {
    1092             :     // just some simple test to see if it's totally broken
    1093           2 :     SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
    1094           4 :     SwPaM aPaM(aIdx);
    1095           2 :     m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("foobar"));
    1096           2 :     aPaM.SetMark();
    1097           2 :     aPaM.GetPoint()->nContent = 0;
    1098           2 :     CPPUNIT_ASSERT_EQUAL(OUString("foobar"), aPaM.GetTxt());
    1099             : 
    1100           4 :     CPPUNIT_ASSERT_EQUAL(OUString("FOOBAR"),
    1101             :             translitTest(*m_pDoc, aPaM,
    1102           2 :                 i18n::TransliterationModules_LOWERCASE_UPPERCASE));
    1103           4 :     CPPUNIT_ASSERT_EQUAL(OUString("Foobar"),
    1104             :             translitTest(*m_pDoc, aPaM,
    1105           2 :                 i18n::TransliterationModulesExtra::TITLE_CASE));
    1106           4 :     CPPUNIT_ASSERT_EQUAL(OUString("fOOBAR"),
    1107             :             translitTest(*m_pDoc, aPaM,
    1108           2 :                 i18n::TransliterationModulesExtra::TOGGLE_CASE));
    1109           4 :     CPPUNIT_ASSERT_EQUAL(OUString("foobar"),
    1110             :             translitTest(*m_pDoc, aPaM,
    1111           2 :                 i18n::TransliterationModules_UPPERCASE_LOWERCASE));
    1112           4 :     CPPUNIT_ASSERT_EQUAL(OUString("Foobar"),
    1113             :             translitTest(*m_pDoc, aPaM,
    1114           2 :                 i18n::TransliterationModulesExtra::SENTENCE_CASE));
    1115           4 :     CPPUNIT_ASSERT_EQUAL(OUString("Foobar"),
    1116             :             translitTest(*m_pDoc, aPaM,
    1117           4 :                 i18n::TransliterationModules_HIRAGANA_KATAKANA));
    1118           2 : }
    1119             : 
    1120           2 : void SwDocTest::testMarkMove()
    1121             : {
    1122           2 :     IDocumentMarkAccess* pMarksAccess = m_pDoc->getIDocumentMarkAccess();
    1123             : 
    1124             :     {
    1125           2 :         SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
    1126           4 :         SwPaM aPaM(aIdx);
    1127           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Paragraph 1"));
    1128           2 :         aPaM.SetMark();
    1129           2 :         aPaM.GetMark()->nContent -= aPaM.GetMark()->nContent.GetIndex();
    1130           2 :         pMarksAccess->makeMark(aPaM, OUString("Para1"), IDocumentMarkAccess::BOOKMARK);
    1131             : 
    1132           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
    1133           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Paragraph 2"));
    1134           2 :         aPaM.SetMark();
    1135           2 :         aPaM.GetMark()->nContent -= aPaM.GetMark()->nContent.GetIndex();
    1136           2 :         pMarksAccess->makeMark(aPaM, OUString("Para2"), IDocumentMarkAccess::BOOKMARK);
    1137             : 
    1138           2 :         m_pDoc->getIDocumentContentOperations().AppendTxtNode(*aPaM.GetPoint());
    1139           2 :         m_pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("Paragraph 3"));
    1140           2 :         aPaM.SetMark();
    1141           2 :         aPaM.GetMark()->nContent -= aPaM.GetMark()->nContent.GetIndex();
    1142           4 :         pMarksAccess->makeMark(aPaM, OUString("Para3"), IDocumentMarkAccess::BOOKMARK);
    1143             :     }
    1144             : 
    1145             :     // join paragraph 2 and 3 and check
    1146             :     {
    1147           2 :         SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -2);
    1148           2 :         SwTxtNode& rParaNode2 = dynamic_cast<SwTxtNode&>(aIdx.GetNode());
    1149           2 :         rParaNode2.JoinNext();
    1150             :     }
    1151           2 :     ::sw::mark::IMark* pBM1 = pMarksAccess->findMark("Para1")->get();
    1152           2 :     ::sw::mark::IMark* pBM2 = pMarksAccess->findMark("Para2")->get();
    1153           2 :     ::sw::mark::IMark* pBM3 = pMarksAccess->findMark("Para3")->get();
    1154             : 
    1155           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 0 , pBM1->GetMarkStart().nContent.GetIndex());
    1156           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 11, pBM1->GetMarkEnd().nContent.GetIndex());
    1157           4 :     CPPUNIT_ASSERT_EQUAL(
    1158             :         pBM1->GetMarkStart().nNode.GetIndex(),
    1159           2 :         pBM1->GetMarkEnd().nNode.GetIndex());
    1160             : 
    1161           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 0 , pBM2->GetMarkStart().nContent.GetIndex());
    1162           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 11, pBM2->GetMarkEnd().nContent.GetIndex());
    1163           4 :     CPPUNIT_ASSERT_EQUAL(
    1164             :         pBM2->GetMarkStart().nNode.GetIndex(),
    1165           2 :         pBM2->GetMarkEnd().nNode.GetIndex());
    1166             : 
    1167           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 11, pBM3->GetMarkStart().nContent.GetIndex());
    1168           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 22, pBM3->GetMarkEnd().nContent.GetIndex());
    1169           4 :     CPPUNIT_ASSERT_EQUAL(
    1170             :         pBM3->GetMarkStart().nNode.GetIndex(),
    1171           2 :         pBM3->GetMarkEnd().nNode.GetIndex());
    1172             : 
    1173           4 :     CPPUNIT_ASSERT_EQUAL(
    1174             :         pBM1->GetMarkStart().nNode.GetIndex()+1,
    1175           2 :         pBM2->GetMarkStart().nNode.GetIndex());
    1176           4 :     CPPUNIT_ASSERT_EQUAL(
    1177             :         pBM2->GetMarkStart().nNode.GetIndex(),
    1178           2 :         pBM3->GetMarkStart().nNode.GetIndex());
    1179             : 
    1180             :     // cut some text
    1181             :     {
    1182           2 :         SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
    1183           4 :         SwPaM aPaM(aIdx, aIdx, -1);
    1184           2 :         aPaM.GetPoint()->nContent += 5;
    1185           2 :         aPaM.GetMark()->nContent += 6;
    1186           4 :         m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aPaM);
    1187             :     }
    1188           2 :     pBM1 = pMarksAccess->findMark("Para1")->get();
    1189           2 :     pBM2 = pMarksAccess->findMark("Para2")->get();
    1190           2 :     pBM3 = pMarksAccess->findMark("Para3")->get();
    1191             : 
    1192           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 0, pBM1->GetMarkStart().nContent.GetIndex());
    1193           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 6, pBM1->GetMarkEnd().nContent.GetIndex());
    1194           4 :     CPPUNIT_ASSERT_EQUAL(
    1195             :         pBM1->GetMarkStart().nNode.GetIndex(),
    1196           2 :         pBM1->GetMarkEnd().nNode.GetIndex());
    1197             : 
    1198           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 6, pBM2->GetMarkStart().nContent.GetIndex());
    1199           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 12, pBM2->GetMarkEnd().nContent.GetIndex());
    1200           4 :     CPPUNIT_ASSERT_EQUAL(
    1201             :         pBM2->GetMarkStart().nNode.GetIndex(),
    1202           2 :         pBM2->GetMarkEnd().nNode.GetIndex());
    1203             : 
    1204           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 12, pBM3->GetMarkStart().nContent.GetIndex());
    1205           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 23, pBM3->GetMarkEnd().nContent.GetIndex());
    1206           4 :     CPPUNIT_ASSERT_EQUAL(
    1207             :         pBM3->GetMarkStart().nNode.GetIndex(),
    1208           2 :         pBM3->GetMarkEnd().nNode.GetIndex());
    1209             : 
    1210           4 :     CPPUNIT_ASSERT_EQUAL(
    1211             :         pBM1->GetMarkStart().nNode.GetIndex(),
    1212           2 :         pBM2->GetMarkStart().nNode.GetIndex());
    1213           4 :     CPPUNIT_ASSERT_EQUAL(
    1214             :         pBM2->GetMarkStart().nNode.GetIndex(),
    1215           2 :         pBM3->GetMarkStart().nNode.GetIndex());
    1216             : 
    1217             :     // split the paragraph
    1218             :     {
    1219           2 :         SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
    1220           4 :         SwPosition aPos(aIdx);
    1221           2 :         aPos.nContent += 8;
    1222           4 :         m_pDoc->getIDocumentContentOperations().SplitNode(aPos, false);
    1223             :     }
    1224           2 :     pBM1 = pMarksAccess->findMark("Para1")->get();
    1225           2 :     pBM2 = pMarksAccess->findMark("Para2")->get();
    1226           2 :     pBM3 = pMarksAccess->findMark("Para3")->get();
    1227             : 
    1228           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 0, pBM1->GetMarkStart().nContent.GetIndex());
    1229           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 6, pBM1->GetMarkEnd().nContent.GetIndex());
    1230           4 :     CPPUNIT_ASSERT_EQUAL(
    1231             :         pBM1->GetMarkStart().nNode.GetIndex(),
    1232           2 :         pBM1->GetMarkEnd().nNode.GetIndex());
    1233             : 
    1234           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 6, pBM2->GetMarkStart().nContent.GetIndex());
    1235           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 4, pBM2->GetMarkEnd().nContent.GetIndex());
    1236           4 :     CPPUNIT_ASSERT_EQUAL(
    1237             :         pBM2->GetMarkStart().nNode.GetIndex()+1,
    1238           2 :         pBM2->GetMarkEnd().nNode.GetIndex());
    1239             : 
    1240           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 4, pBM3->GetMarkStart().nContent.GetIndex());
    1241           2 :     CPPUNIT_ASSERT_EQUAL((sal_Int32) 15, pBM3->GetMarkEnd().nContent.GetIndex());
    1242           4 :     CPPUNIT_ASSERT_EQUAL(
    1243             :         pBM3->GetMarkStart().nNode.GetIndex(),
    1244           2 :         pBM3->GetMarkEnd().nNode.GetIndex());
    1245             : 
    1246           4 :     CPPUNIT_ASSERT_EQUAL(
    1247             :         pBM1->GetMarkStart().nNode.GetIndex(),
    1248           2 :         pBM2->GetMarkStart().nNode.GetIndex());
    1249           4 :     CPPUNIT_ASSERT_EQUAL(
    1250             :         pBM2->GetMarkEnd().nNode.GetIndex(),
    1251           2 :         pBM3->GetMarkEnd().nNode.GetIndex());
    1252           2 : }
    1253             : 
    1254          50 : void SwDocTest::setUp()
    1255             : {
    1256          50 :     BootstrapFixture::setUp();
    1257             : 
    1258          50 :     SwGlobals::ensure();
    1259          50 :     m_pDoc = new SwDoc;
    1260          50 :     m_xDocShRef = new SwDocShell(m_pDoc, SFX_CREATE_MODE_EMBEDDED);
    1261          50 :     m_xDocShRef->DoInitNew(0);
    1262          50 : }
    1263             : 
    1264          50 : void SwDocTest::tearDown()
    1265             : {
    1266          50 :     m_pDoc = 0; // deleted by DoClose()
    1267          50 :     m_xDocShRef->DoClose();
    1268          50 :     m_xDocShRef.Clear();
    1269             : 
    1270          50 :     BootstrapFixture::tearDown();
    1271          50 : }
    1272             : 
    1273           2 : CPPUNIT_TEST_SUITE_REGISTRATION(SwDocTest);
    1274             : 
    1275           8 : CPPUNIT_PLUGIN_IMPLEMENT();
    1276             : 
    1277             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10