From c8956344af6d5ffd443b44808f34841e70ffaac0 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Sun, 3 Feb 2013 12:39:21 +0100 Subject: sw: sw_swdoc_test -> sw_uwriter To be consistent to sc_ucalc and sd_uimpress. Change-Id: Id6b09bacdf19fb7c524f11352ba81cd630535a74 --- sw/CppunitTest_sw_swdoc_test.mk | 110 ----- sw/CppunitTest_sw_uwriter.mk | 110 +++++ sw/Module_sw.mk | 2 +- sw/qa/core/swdoc-test.cxx | 921 ---------------------------------------- sw/qa/core/uwriter.cxx | 921 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1032 insertions(+), 1032 deletions(-) delete mode 100644 sw/CppunitTest_sw_swdoc_test.mk create mode 100644 sw/CppunitTest_sw_uwriter.mk delete mode 100644 sw/qa/core/swdoc-test.cxx create mode 100644 sw/qa/core/uwriter.cxx (limited to 'sw') diff --git a/sw/CppunitTest_sw_swdoc_test.mk b/sw/CppunitTest_sw_swdoc_test.mk deleted file mode 100644 index 0be24f3e953a..000000000000 --- a/sw/CppunitTest_sw_swdoc_test.mk +++ /dev/null @@ -1,110 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -#************************************************************************* -# Version: MPL 1.1 / GPLv3+ / LGPLv3+ -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License or as specified alternatively below. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# Major Contributor(s): -# Copyright (C) 2011 Red Hat, Inc., Caolán McNamara -# (initial developer) -# -# All Rights Reserved. -# -# For minor contributions see the git repository. -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 3 or later (the "GPLv3+"), or -# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), -# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable -# instead of those above. -#************************************************************************* - -$(eval $(call gb_CppunitTest_CppunitTest,sw_swdoc_test)) - -$(eval $(call gb_CppunitTest_add_exception_objects,sw_swdoc_test, \ - sw/qa/core/swdoc-test \ - sw/qa/core/Test-BigPtrArray \ -)) - -$(eval $(call gb_CppunitTest_use_library_objects,sw_swdoc_test,sw)) - -$(eval $(call gb_CppunitTest_use_libraries,sw_swdoc_test, \ - avmedia \ - basegfx \ - comphelper \ - cppu \ - cppuhelper \ - drawinglayer \ - editeng \ - i18nisolang1 \ - i18nutil \ - lng \ - oox \ - sal \ - salhelper \ - sax \ - sb \ - sfx \ - sot \ - svl \ - svt \ - svx \ - svxcore \ - swd \ - test \ - tk \ - tl \ - ucbhelper \ - utl \ - vbahelper \ - vcl \ - xo \ - $(gb_UWINAPI) \ -)) - -$(eval $(call gb_CppunitTest_use_externals,sw_swdoc_test,\ - boost_headers \ - icuuc \ - libxml2 \ -)) - -$(eval $(call gb_CppunitTest_set_include,sw_swdoc_test,\ - -I$(SRCDIR)/sw/source/ui/inc \ - -I$(SRCDIR)/sw/source/core/inc \ - -I$(SRCDIR)/sw/inc \ - $$(INCLUDE) \ -)) - -$(eval $(call gb_CppunitTest_use_api,sw_swdoc_test,\ - offapi \ - udkapi \ -)) - -$(eval $(call gb_CppunitTest_use_ure,sw_swdoc_test)) - -$(eval $(call gb_CppunitTest_use_components,sw_swdoc_test,\ - comphelper/util/comphelp \ - configmgr/source/configmgr \ - fileaccess/source/fileacc \ - framework/util/fwk \ - i18npool/util/i18npool \ - package/util/package2 \ - package/source/xstor/xstor \ - sfx2/util/sfx \ - ucb/source/core/ucb1 \ - ucb/source/ucp/file/ucpfile1 \ - unotools/util/utl \ - unoxml/source/service/unoxml \ -)) - -$(eval $(call gb_CppunitTest_use_configuration,sw_swdoc_test)) - -# vim: set noet sw=4 ts=4: diff --git a/sw/CppunitTest_sw_uwriter.mk b/sw/CppunitTest_sw_uwriter.mk new file mode 100644 index 000000000000..4f25f5c2bdef --- /dev/null +++ b/sw/CppunitTest_sw_uwriter.mk @@ -0,0 +1,110 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# Version: MPL 1.1 / GPLv3+ / LGPLv3+ +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License or as specified alternatively below. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# Major Contributor(s): +# Copyright (C) 2011 Red Hat, Inc., Caolán McNamara +# (initial developer) +# +# All Rights Reserved. +# +# For minor contributions see the git repository. +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 3 or later (the "GPLv3+"), or +# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), +# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable +# instead of those above. +#************************************************************************* + +$(eval $(call gb_CppunitTest_CppunitTest,sw_uwriter)) + +$(eval $(call gb_CppunitTest_add_exception_objects,sw_uwriter, \ + sw/qa/core/uwriter \ + sw/qa/core/Test-BigPtrArray \ +)) + +$(eval $(call gb_CppunitTest_use_library_objects,sw_uwriter,sw)) + +$(eval $(call gb_CppunitTest_use_libraries,sw_uwriter, \ + avmedia \ + basegfx \ + comphelper \ + cppu \ + cppuhelper \ + drawinglayer \ + editeng \ + i18nisolang1 \ + i18nutil \ + lng \ + oox \ + sal \ + salhelper \ + sax \ + sb \ + sfx \ + sot \ + svl \ + svt \ + svx \ + svxcore \ + swd \ + test \ + tk \ + tl \ + ucbhelper \ + utl \ + vbahelper \ + vcl \ + xo \ + $(gb_UWINAPI) \ +)) + +$(eval $(call gb_CppunitTest_use_externals,sw_uwriter,\ + boost_headers \ + icuuc \ + libxml2 \ +)) + +$(eval $(call gb_CppunitTest_set_include,sw_uwriter,\ + -I$(SRCDIR)/sw/source/ui/inc \ + -I$(SRCDIR)/sw/source/core/inc \ + -I$(SRCDIR)/sw/inc \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_CppunitTest_use_api,sw_uwriter,\ + offapi \ + udkapi \ +)) + +$(eval $(call gb_CppunitTest_use_ure,sw_uwriter)) + +$(eval $(call gb_CppunitTest_use_components,sw_uwriter,\ + comphelper/util/comphelp \ + configmgr/source/configmgr \ + fileaccess/source/fileacc \ + framework/util/fwk \ + i18npool/util/i18npool \ + package/util/package2 \ + package/source/xstor/xstor \ + sfx2/util/sfx \ + ucb/source/core/ucb1 \ + ucb/source/ucp/file/ucpfile1 \ + unotools/util/utl \ + unoxml/source/service/unoxml \ +)) + +$(eval $(call gb_CppunitTest_use_configuration,sw_uwriter)) + +# vim: set noet sw=4 ts=4: diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk index 6abd3212cc7b..d4ea0acdf84a 100644 --- a/sw/Module_sw.mk +++ b/sw/Module_sw.mk @@ -38,7 +38,7 @@ $(eval $(call gb_Module_add_targets,sw,\ endif $(eval $(call gb_Module_add_check_targets,sw,\ - CppunitTest_sw_swdoc_test \ + CppunitTest_sw_uwriter \ )) $(eval $(call gb_Module_add_slowcheck_targets,sw,\ diff --git a/sw/qa/core/swdoc-test.cxx b/sw/qa/core/swdoc-test.cxx deleted file mode 100644 index 189a25cf2476..000000000000 --- a/sw/qa/core/swdoc-test.cxx +++ /dev/null @@ -1,921 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * Version: MPL 1.1 / GPLv3+ / LGPLv3+ - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Initial Developer of the Original Code is - * Thorsten Behrens - * Portions created by the Initial Developer are Copyright (C) 2011 the - * Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Thorsten Behrens - * Caolán McNamara - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 3 or later (the "GPLv3+"), or - * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), - * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable - * instead of those above. - */ - -#include -#include - -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include "breakit.hxx" -#include "doc.hxx" -#include "docsh.hxx" -#include "docstat.hxx" -#include "docufld.hxx" -#include "fmtanchr.hxx" -#include "init.hxx" -#include "ndtxt.hxx" -#include "shellio.hxx" -#include "shellres.hxx" -#include "swcrsr.hxx" -#include "swscanner.hxx" -#include "swmodule.hxx" -#include "swtypes.hxx" -#include "fmtftn.hxx" -#include "fmtrfmrk.hxx" -#include "fmtfld.hxx" -#include "redline.hxx" -#include "docary.hxx" -#include "modeltoviewhelper.hxx" -#include "scriptinfo.hxx" - -SV_DECL_REF(SwDocShell) -SV_IMPL_REF(SwDocShell) - -using namespace ::com::sun::star; - -/* Implementation of Swdoc-Test class */ - -class SwDocTest : public test::BootstrapFixture -{ -public: - virtual void setUp(); - virtual void tearDown(); - - void randomTest(); - void testPageDescName(); - void testFileNameFields(); - void testDocStat(); - void testModelToViewHelper(); - void testSwScanner(); - void testUserPerceivedCharCount(); - void testGraphicAnchorDeletion(); - void testFdo57938(); - - CPPUNIT_TEST_SUITE(SwDocTest); - CPPUNIT_TEST(randomTest); - CPPUNIT_TEST(testPageDescName); - CPPUNIT_TEST(testFileNameFields); - CPPUNIT_TEST(testDocStat); - CPPUNIT_TEST(testModelToViewHelper); - CPPUNIT_TEST(testSwScanner); - CPPUNIT_TEST(testUserPerceivedCharCount); - CPPUNIT_TEST(testGraphicAnchorDeletion); - CPPUNIT_TEST(testFdo57938); - CPPUNIT_TEST_SUITE_END(); - -private: - SwDoc *m_pDoc; - SwDocShellRef m_xDocShRef; -}; - -void SwDocTest::testPageDescName() -{ - ShellResource aShellResources; - - std::vector aResults; - - //These names must be unique for each different combination, otherwise - //duplicate page description names may exist, which will causes lookup - //by name to be incorrect, and so the corresponding export to .odt - aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::NORMAL_PAGE)); - aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::FIRST_PAGE)); - aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::FOLLOW_PAGE)); - - std::sort(aResults.begin(), aResults.end()); - aResults.erase(std::unique(aResults.begin(), aResults.end()), aResults.end()); - - CPPUNIT_ASSERT_MESSAGE("GetPageDescName results must be unique", aResults.size() == 3); -} - -//See https://bugs.freedesktop.org/show_bug.cgi?id=32463 -void SwDocTest::testFileNameFields() -{ - //Here's a file name with some chars in it that will be %% encoded, when expanding - //SwFileNameFields we want to restore the original readable filename - utl::TempFile aTempFile(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("demo [name]"))); - aTempFile.EnableKillingFile(); - - INetURLObject aTempFileURL(aTempFile.GetURL()); - String sFileURL = aTempFileURL.GetMainURL(INetURLObject::NO_DECODE); - SfxMedium aDstMed(sFileURL, STREAM_STD_READWRITE); - - SfxFilter aFilter( - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text")), - rtl::OUString(), 0, 0, rtl::OUString(), 0, rtl::OUString(), - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TEXT")), rtl::OUString() ); - aDstMed.SetFilter(&aFilter); - - m_xDocShRef->DoSaveAs(aDstMed); - m_xDocShRef->DoSaveCompleted(&aDstMed); - - const INetURLObject &rUrlObj = m_xDocShRef->GetMedium()->GetURLObject(); - - SwFileNameFieldType aNameField(m_pDoc); - - { - rtl::OUString sResult(aNameField.Expand(FF_NAME)); - rtl::OUString sExpected(rUrlObj.getName(INetURLObject::LAST_SEGMENT, - true,INetURLObject::DECODE_WITH_CHARSET)); - CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected); - } - - { - rtl::OUString sResult(aNameField.Expand(FF_PATHNAME)); - rtl::OUString sExpected(rUrlObj.GetFull()); - CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected); - } - - { - rtl::OUString sResult(aNameField.Expand(FF_PATH)); - INetURLObject aTemp(rUrlObj); - aTemp.removeSegment(); - rtl::OUString sExpected(aTemp.PathToFileName()); - CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected); - } - - { - rtl::OUString sResult(aNameField.Expand(FF_NAME_NOEXT)); - rtl::OUString sExpected(rUrlObj.getName(INetURLObject::LAST_SEGMENT, - true,INetURLObject::DECODE_WITH_CHARSET)); - //Chop off .tmp - sExpected = sExpected.copy(0, sExpected.getLength() - 4); - CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected); - } - - m_xDocShRef->DoInitNew(0); -} - -//See http://lists.freedesktop.org/archives/libreoffice/2011-August/016666.html -//Remove unnecessary parameter to IDocumentStatistics::UpdateDocStat for -//motivation -void SwDocTest::testDocStat() -{ - CPPUNIT_ASSERT_MESSAGE("Expected initial 0 count", m_pDoc->GetDocStat().nChar == 0); - - SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1); - SwPaM aPaM(aIdx); - - rtl::OUString sText(RTL_CONSTASCII_USTRINGPARAM("Hello World")); - m_pDoc->InsertString(aPaM, sText); - - CPPUNIT_ASSERT_MESSAGE("Should still be non-updated 0 count", m_pDoc->GetDocStat().nChar == 0); - - SwDocStat aDocStat = m_pDoc->GetUpdatedDocStat(); - sal_uLong nLen = static_cast(sText.getLength()); - - CPPUNIT_ASSERT_MESSAGE("Should now have updated count", aDocStat.nChar == nLen); - - CPPUNIT_ASSERT_MESSAGE("And cache is updated too", m_pDoc->GetDocStat().nChar == nLen); -} - -//For UI character counts we should follow UAX#29 and display the user -//perceived characters, not the number of codepoints, nor the number of code -//units http://unicode.org/reports/tr29/ -void SwDocTest::testUserPerceivedCharCount() -{ - SwBreakIt *pBreakIter = SwBreakIt::Get(); - - //Grapheme example, two different unicode code-points perceived by the user as a single - //glyph - const sal_Unicode ALEF_QAMATS [] = { 0x05D0, 0x05B8 }; - ::rtl::OUString sALEF_QAMATS(ALEF_QAMATS, SAL_N_ELEMENTS(ALEF_QAMATS)); - sal_Int32 nGraphemeCount = pBreakIter->getGraphemeCount(sALEF_QAMATS); - CPPUNIT_ASSERT_MESSAGE("Grapheme Count should be 1", nGraphemeCount == 1); - - //Surrogate pair example, one single unicode code-point (U+1D11E) - //represented as two code units in UTF-16 - const sal_Unicode GCLEF[] = { 0xD834, 0xDD1E }; - ::rtl::OUString sGCLEF(GCLEF, SAL_N_ELEMENTS(GCLEF)); - sal_Int32 nCount = pBreakIter->getGraphemeCount(sGCLEF); - CPPUNIT_ASSERT_MESSAGE("Surrogate Pair should be counted as single character", nCount == 1); -} - -void SwDocTest::testModelToViewHelper() -{ - SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1); - SwPaM aPaM(aIdx); - - { - SwFmtFtn aFtn; - aFtn.SetNumStr(rtl::OUString("foo")); - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, rtl::OUString("AAAAA BBBBB ")); - SwTxtNode* pTxtNode = aPaM.GetNode()->GetTxtNode(); - xub_StrLen nPos = aPaM.GetPoint()->nContent.GetIndex(); - pTxtNode->InsertItem(aFtn, nPos, nPos); - m_pDoc->InsertString(aPaM, rtl::OUString(" CCCCC ")); - nPos = aPaM.GetPoint()->nContent.GetIndex(); - pTxtNode->InsertItem(aFtn, nPos, nPos); - m_pDoc->InsertString(aPaM, rtl::OUString(" DDDDD")); - CPPUNIT_ASSERT(pTxtNode->GetTxt().Len() == (4*5) + 5 + 2); - - //set start of selection to first B - aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 6); - aPaM.SetMark(); - //set end of selection to last C - aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 14); - //set character attribute hidden on range - SvxCharHiddenItem aHidden(true, RES_CHRATR_HIDDEN); - m_pDoc->InsertPoolItem(aPaM, aHidden, 0 ); - - //turn on red-lining and show changes - m_pDoc->SetRedlineMode(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE|nsRedlineMode_t::REDLINE_SHOW_INSERT); - CPPUNIT_ASSERT_MESSAGE("redlining should be on", m_pDoc->IsRedlineOn()); - CPPUNIT_ASSERT_MESSAGE("redlines should be visible", IDocumentRedlineAccess::IsShowChanges(m_pDoc->GetRedlineMode())); - - //set start of selection to last A - aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 4); - aPaM.SetMark(); - //set end of selection to second last B - aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 9); - m_pDoc->DeleteAndJoin(aPaM); //redline-aware deletion api - - { - ModelToViewHelper aModelToViewHelper(*pTxtNode, PASSTHROUGH); - rtl::OUString sViewText = aModelToViewHelper.getViewText(); - rtl::OUString sModelText = pTxtNode->GetTxt(); - CPPUNIT_ASSERT(sViewText == sModelText); - } - - { - ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS); - rtl::OUString sViewText = aModelToViewHelper.getViewText(); - CPPUNIT_ASSERT(sViewText == "AAAAA BBBBB foo CCCCC foo DDDDD"); - } - - { - ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEINVISIBLE); - rtl::OUString sViewText = aModelToViewHelper.getViewText(); - rtl::OUStringBuffer aBuffer; - aBuffer.append("AAAAA CCCCC "); - aBuffer.append(CH_TXTATR_BREAKWORD); - aBuffer.append(" DDDDD"); - CPPUNIT_ASSERT(sViewText == aBuffer.makeStringAndClear()); - } - - { - ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEREDLINED); - rtl::OUString sViewText = aModelToViewHelper.getViewText(); - rtl::OUStringBuffer aBuffer; - aBuffer.append("AAAABB "); - aBuffer.append(CH_TXTATR_BREAKWORD); - aBuffer.append(" CCCCC "); - aBuffer.append(CH_TXTATR_BREAKWORD); - aBuffer.append(" DDDDD"); - CPPUNIT_ASSERT(sViewText == aBuffer.makeStringAndClear()); - } - - { - ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEINVISIBLE); - rtl::OUString sViewText = aModelToViewHelper.getViewText(); - CPPUNIT_ASSERT(sViewText == "AAAAA CCCCC foo DDDDD"); - } - - { - ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEREDLINED); - rtl::OUString sViewText = aModelToViewHelper.getViewText(); - CPPUNIT_ASSERT(sViewText == "AAAABB foo CCCCC foo DDDDD"); - } - - { - ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEINVISIBLE | HIDEREDLINED); - rtl::OUString sViewText = aModelToViewHelper.getViewText(); - rtl::OUStringBuffer aBuffer; - aBuffer.append("AAAACCCCC "); - aBuffer.append(CH_TXTATR_BREAKWORD); - aBuffer.append(" DDDDD"); - CPPUNIT_ASSERT(sViewText == aBuffer.makeStringAndClear()); - } - - { - ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEINVISIBLE | HIDEREDLINED); - rtl::OUString sViewText = aModelToViewHelper.getViewText(); - CPPUNIT_ASSERT(sViewText == "AAAACCCCC foo DDDDD"); - } - } -} - -void SwDocTest::testSwScanner() -{ - SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1); - SwPaM aPaM(aIdx); - - SwTxtNode* pTxtNode = aPaM.GetNode()->GetTxtNode(); - - CPPUNIT_ASSERT_MESSAGE("Has Text Node", pTxtNode); - - //See https://bugs.freedesktop.org/show_bug.cgi?id=40449 - //See https://bugs.freedesktop.org/show_bug.cgi?id=39365 - //Use a temporary rtl::OUString as the arg, as that's the trouble behind - //fdo#40449 and fdo#39365 - { - SwScanner aScanner(*pTxtNode, - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hello World")), - 0, ModelToViewHelper(), i18n::WordType::DICTIONARY_WORD, 0, - RTL_CONSTASCII_LENGTH("Hello World")); - - bool bFirstOk = aScanner.NextWord(); - CPPUNIT_ASSERT_MESSAGE("First Token", bFirstOk); - const rtl::OUString &rHello = aScanner.GetWord(); - CPPUNIT_ASSERT_MESSAGE("Should be Hello", - rHello.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Hello"))); - - bool bSecondOk = aScanner.NextWord(); - CPPUNIT_ASSERT_MESSAGE("Second Token", bSecondOk); - const rtl::OUString &rWorld = aScanner.GetWord(); - CPPUNIT_ASSERT_MESSAGE("Should be World", - rWorld.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("World"))); - } - - //See https://www.libreoffice.org/bugzilla/show_bug.cgi?id=45271 - { - const sal_Unicode IDEOGRAPHICFULLSTOP_D[] = { 0x3002, 'D' }; - - m_pDoc->InsertString(aPaM, rtl::OUString(IDEOGRAPHICFULLSTOP_D, - SAL_N_ELEMENTS(IDEOGRAPHICFULLSTOP_D))); - - SvxLanguageItem aCJKLangItem( LANGUAGE_CHINESE_SIMPLIFIED, RES_CHRATR_CJK_LANGUAGE ); - SvxLanguageItem aWestLangItem( LANGUAGE_ENGLISH_US, RES_CHRATR_LANGUAGE ); - m_pDoc->InsertPoolItem(aPaM, aCJKLangItem, 0 ); - m_pDoc->InsertPoolItem(aPaM, aWestLangItem, 0 ); - - SwDocStat aDocStat; - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(IDEOGRAPHICFULLSTOP_D)); - - CPPUNIT_ASSERT_MESSAGE("Should be 2", aDocStat.nChar == 2); - CPPUNIT_ASSERT_MESSAGE("Should be 2", aDocStat.nCharExcludingSpaces == 2); - } - { - const sal_Unicode test[] = - { - 0x3053, 0x306E, 0x65E5, 0x672C, 0x8A9E, 0x306F, 0x6B63, 0x3057, - 0x304F, 0x6570, 0x3048, 0x3089, 0x308C, 0x308B, 0x3067, 0x3057, - 0x3087, 0x3046, 0x304B, 0x3002, 0x0041, 0x006E, 0x0064, 0x0020, - 0x006C, 0x0065, 0x0074, 0x0027, 0x0073, 0x0020, 0x0074, 0x0068, - 0x0072, 0x006F, 0x0077, 0x0020, 0x0073, 0x006F, 0x006D, 0x0065, - 0x0020, 0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068, - 0x0020, 0x0069, 0x006E, 0x0020, 0x0074, 0x006F, 0x0020, 0x006D, - 0x0061, 0x006B, 0x0065, 0x0020, 0x0069, 0x0074, 0x0020, 0x0069, - 0x006E, 0x0074, 0x0065, 0x0072, 0x0065, 0x0073, 0x0074, 0x0069, - 0x006E, 0x0067, 0x002E, 0x0020, 0x0020, 0x305D, 0x3057, 0x3066, - 0x3001, 0x307E, 0x305F, 0x65E5, 0x672C, 0x8A9E, 0x3000, 0x3000, - 0x3067, 0x3082, 0x4ECA, 0x56DE, 0x306F, 0x7A7A, 0x767D, 0x3092, - 0x3000, 0x3000, 0x5165, 0x308C, 0x307E, 0x3057, 0x305F, 0x3002, - 0x0020, 0x0020, 0x0053, 0x006F, 0x0020, 0x0068, 0x006F, 0x0077, - 0x0020, 0x0064, 0x006F, 0x0065, 0x0073, 0x0020, 0x0074, 0x0068, - 0x0069, 0x0073, 0x0020, 0x0064, 0x006F, 0x003F, 0x0020, 0x0020 - }; - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, rtl::OUString(test, - SAL_N_ELEMENTS(test))); - - SvxLanguageItem aCJKLangItem( LANGUAGE_JAPANESE, RES_CHRATR_CJK_LANGUAGE ); - SvxLanguageItem aWestLangItem( LANGUAGE_ENGLISH_US, RES_CHRATR_LANGUAGE ); - m_pDoc->InsertPoolItem(aPaM, aCJKLangItem, 0 ); - m_pDoc->InsertPoolItem(aPaM, aWestLangItem, 0 ); - - SwDocStat aDocStat; - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(test)); - CPPUNIT_ASSERT_MESSAGE("58 words", aDocStat.nWord == 58); - CPPUNIT_ASSERT_MESSAGE("43 Asian characters and Korean syllables", aDocStat.nAsianWord == 43); - CPPUNIT_ASSERT_MESSAGE("105 non-whitespace chars", aDocStat.nCharExcludingSpaces == 105); - CPPUNIT_ASSERT_MESSAGE("128 characters", aDocStat.nChar == 128); - } - - //See https://issues.apache.org/ooo/show_bug.cgi?id=89042 - //See https://bugs.freedesktop.org/show_bug.cgi?id=53399 - { - SwDocStat aDocStat; - - const sal_Unicode aShouldBeThree[] = { - 0x0053, 0x0068, 0x006F, 0x0075, 0x006C, 0x0064, 0x0020, - 0x2018, 0x0062, 0x0065, 0x0020, 0x0074, 0x0068, 0x0072, - 0x0065, 0x0065, 0x2019 - }; - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, rtl::OUString(aShouldBeThree, SAL_N_ELEMENTS(aShouldBeThree))); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(aShouldBeThree)); - CPPUNIT_ASSERT_MESSAGE("Should be 3", aDocStat.nWord == 3); - - const sal_Unicode aShouldBeFive[] = { - // f r e n c h space - 0x0046, 0x0072, 0x0065, 0x006E, 0x0063, 0x0068, 0x0020, - // << nbsp s a v o i - 0x00AB, 0x00A0, 0x0073, 0x0061, 0x0076, 0x006F, 0x0069, - // r nnbsp c a l c u - 0x0072, 0x202f, 0x0063, 0x0061, 0x006C, 0x0063, 0x0075, - // l e r idspace >> - 0x006C, 0x0065, 0x0072, 0x3000, 0x00BB - }; - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, rtl::OUString(aShouldBeFive, SAL_N_ELEMENTS(aShouldBeFive))); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - aDocStat.Reset(); - pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(aShouldBeFive)); - CPPUNIT_ASSERT_MESSAGE("Should be 5", aDocStat.nWord == 5); - } - - //See https://bugs.freedesktop.org/show_bug.cgi?id=49629 - { - SwDocStat aDocStat; - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, rtl::OUString("Apple")); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - xub_StrLen nPos = aPaM.GetPoint()->nContent.GetIndex(); - SwFmtFtn aFtn; - aFtn.SetNumStr(rtl::OUString("banana")); - SwTxtAttr* pTA = pTxtNode->InsertItem(aFtn, nPos, nPos); - CPPUNIT_ASSERT(pTA); - CPPUNIT_ASSERT(pTxtNode->Len() == 6); //Apple + 0x02 - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 1); - CPPUNIT_ASSERT_MESSAGE("footnote should be expanded", aDocStat.nChar == 11); - - xub_StrLen nNextPos = aPaM.GetPoint()->nContent.GetIndex(); - CPPUNIT_ASSERT(nNextPos == nPos+1); - SwFmtRefMark aRef(rtl::OUString("refmark")); - pTA = pTxtNode->InsertItem(aRef, nNextPos, nNextPos); - CPPUNIT_ASSERT(pTA); - - aDocStat.Reset(); - pTxtNode->SetWordCountDirty(true); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 1); - CPPUNIT_ASSERT_MESSAGE("refmark anchor should not be counted", aDocStat.nChar == 11); - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, rtl::OUString("Apple")); - - DateTime aDate(DateTime::SYSTEM); - SwPostItField aPostIt( - (SwPostItFieldType*)m_pDoc->GetSysFldType(RES_POSTITFLD), rtl::OUString("An Author"), - rtl::OUString("Some Text"), rtl::OUString("Initials"), OUString("Name"), aDate ); - m_pDoc->InsertPoolItem(aPaM, SwFmtFld(aPostIt), 0); - - m_pDoc->InsertString(aPaM, rtl::OUString("Apple")); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - aDocStat.Reset(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 1); - CPPUNIT_ASSERT_MESSAGE("postit anchor should effectively not exist", aDocStat.nChar == 10); - CPPUNIT_ASSERT(pTxtNode->Len() == 11); - - aDocStat.Reset(); - } - - //See https://bugs.freedesktop.org/show_bug.cgi?id=46757 - { - SwDocStat aDocStat; - - const char aString[] = "Lorem ipsum"; - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, rtl::OUString(aString)); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast(2)); - - //turn on red-lining and show changes - m_pDoc->SetRedlineMode(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE|nsRedlineMode_t::REDLINE_SHOW_INSERT); - CPPUNIT_ASSERT_MESSAGE("redlining should be on", m_pDoc->IsRedlineOn()); - CPPUNIT_ASSERT_MESSAGE("redlines should be visible", IDocumentRedlineAccess::IsShowChanges(m_pDoc->GetRedlineMode())); - - //delete everything except the first word - aPaM.SetMark(); //set start of selection to current pos - aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 5); //set end of selection to fifth char of current node - m_pDoc->DeleteAndJoin(aPaM); //redline-aware deletion api - CPPUNIT_ASSERT_MESSAGE("real underlying text should be the same", pTxtNode->GetTxt().EqualsAscii(aString)); - - aDocStat.Reset(); - pTxtNode->SetWordCountDirty(true); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //but word-counting the text should only count the non-deleted text - CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast(1)); - - pTxtNode->SetWordCountDirty(true); - - //keep red-lining on but hide changes - m_pDoc->SetRedlineMode(nsRedlineMode_t::REDLINE_ON); - CPPUNIT_ASSERT_MESSAGE("redlining should be still on", m_pDoc->IsRedlineOn()); - CPPUNIT_ASSERT_MESSAGE("redlines should be invisible", !IDocumentRedlineAccess::IsShowChanges(m_pDoc->GetRedlineMode())); - - aDocStat.Reset(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //but word-counting the text should only count the non-deleted text - CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast(1)); - - rtl::OUString sLorem = pTxtNode->GetTxt(); - CPPUNIT_ASSERT(sLorem == "Lorem"); - - const SwRedlineTbl& rTbl = m_pDoc->GetRedlineTbl(); - - SwNodes& rNds = m_pDoc->GetNodes(); - CPPUNIT_ASSERT(rTbl.size() == 1); - - SwNodeIndex* pNodeIdx = rTbl[0]->GetContentIdx(); - CPPUNIT_ASSERT(pNodeIdx); - - pTxtNode = rNds[ pNodeIdx->GetIndex() + 1 ]->GetTxtNode(); //first deleted txtnode - CPPUNIT_ASSERT(pTxtNode); - - rtl::OUString sIpsum = pTxtNode->GetTxt(); - CPPUNIT_ASSERT(sIpsum == " ipsum"); - - aDocStat.Reset(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //word-counting the text should only count the non-deleted text, and this whole chunk should be ignored - CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast(0)); - CPPUNIT_ASSERT_EQUAL(aDocStat.nChar, static_cast(0)); - } - - //See https://bugs.freedesktop.org/show_bug.cgi?id=38983 - { - SwDocStat aDocStat; - - rtl::OUString sTemplate("ThisXis a test."); - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, sTemplate.replace('X', ' ')); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 4 && - aDocStat.nCharExcludingSpaces == 12 && - aDocStat.nChar == 15); - aDocStat.Reset(); - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, sTemplate.replaceAll(rtl::OUString('X'), rtl::OUString(" = "))); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 5 && - aDocStat.nCharExcludingSpaces == 13 && - aDocStat.nChar == 17); - aDocStat.Reset(); - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, sTemplate.replaceAll(rtl::OUString('X'), rtl::OUString(" _ "))); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 5 && - aDocStat.nCharExcludingSpaces == 13 && - aDocStat.nChar == 17); - aDocStat.Reset(); - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, sTemplate.replaceAll(rtl::OUString('X'), rtl::OUString(" -- "))); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 5 && - aDocStat.nCharExcludingSpaces == 14 && - aDocStat.nChar == 18); - aDocStat.Reset(); - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, sTemplate.replace('X', '_')); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 3 && - aDocStat.nCharExcludingSpaces == 13 && - aDocStat.nChar == 15); - aDocStat.Reset(); - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, sTemplate.replace('X', '-')); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 3 && - aDocStat.nCharExcludingSpaces == 13 && - aDocStat.nChar == 15); - aDocStat.Reset(); - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2012)); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 3 && - aDocStat.nCharExcludingSpaces == 13 && - aDocStat.nChar == 15); - aDocStat.Reset(); - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2015)); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 3 && - aDocStat.nCharExcludingSpaces == 13 && - aDocStat.nChar == 15); - aDocStat.Reset(); - - //But default configuration should, msword-alike treak emdash - //and endash as word seperators for word-counting - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2013)); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 4 && - aDocStat.nCharExcludingSpaces == 13 && - aDocStat.nChar == 15); - aDocStat.Reset(); - - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2014)); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 4 && - aDocStat.nCharExcludingSpaces == 13 && - aDocStat.nChar == 15); - aDocStat.Reset(); - - const sal_Unicode aChunk[] = {' ', 0x2013, ' '}; - rtl::OUString sChunk(aChunk, SAL_N_ELEMENTS(aChunk)); - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - m_pDoc->InsertString(aPaM, sTemplate.replaceAll(rtl::OUString('X'), sChunk)); - pTxtNode = aPaM.GetNode()->GetTxtNode(); - pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); - CPPUNIT_ASSERT(aDocStat.nWord == 4 && - aDocStat.nCharExcludingSpaces == 13 && - aDocStat.nChar == 17); - aDocStat.Reset(); - } -} - -//See https://bugs.freedesktop.org/show_bug.cgi?id=40599 -void SwDocTest::testGraphicAnchorDeletion() -{ - CPPUNIT_ASSERT_MESSAGE("Expected initial 0 count", m_pDoc->GetDocStat().nChar == 0); - - SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1); - SwPaM aPaM(aIdx); - - m_pDoc->InsertString(aPaM, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Paragraph 1"))); - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - - m_pDoc->InsertString(aPaM, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("graphic anchor>><nNode; - m_pDoc->AppendTxtNode(*aPaM.GetPoint()); - - m_pDoc->InsertString(aPaM, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Paragraph 3"))); - - aPaM.GetPoint()->nNode = nPara2; - aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), RTL_CONSTASCII_LENGTH("graphic anchor>>")); - - //Insert a graphic at X of >>X<< in paragraph 2 - SfxItemSet aFlySet(m_pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1); - SwFmtAnchor aAnchor(FLY_AS_CHAR); - aAnchor.SetAnchor(aPaM.GetPoint()); - aFlySet.Put(aAnchor); - SwFlyFrmFmt *pFrame = m_pDoc->Insert(aPaM, rtl::OUString(), rtl::OUString(), NULL, &aFlySet, NULL, NULL); - CPPUNIT_ASSERT_MESSAGE("Expected frame", pFrame != NULL); - - CPPUNIT_ASSERT_MESSAGE("Should be 1 graphic", m_pDoc->GetFlyCount(FLYCNTTYPE_GRF) == 1); - - //Delete >X< - aPaM.GetPoint()->nNode = nPara2; - aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), - RTL_CONSTASCII_LENGTH("graphic anchor>><")+1); - aPaM.SetMark(); - aPaM.GetPoint()->nNode = nPara2; - aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), RTL_CONSTASCII_LENGTH("graphic anchor>")); - m_pDoc->DeleteRange(aPaM); - -#ifdef DEBUG_AS_HTML - { - SvFileStream aPasteDebug(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( - "cppunitDEBUG.html")), STREAM_WRITE|STREAM_TRUNC); - WriterRef xWrt; - GetHTMLWriter( String(), String(), xWrt ); - SwWriter aDbgWrt( aPasteDebug, *m_pDoc ); - aDbgWrt.Write( xWrt ); - } -#endif - - CPPUNIT_ASSERT_MESSAGE("Should be 0 graphics", m_pDoc->GetFlyCount(FLYCNTTYPE_GRF) == 0); - - //Now, if instead we swap FLY_AS_CHAR (inline graphic) to FLY_AT_CHAR (anchored to character) - //and repeat the above, graphic is *not* deleted, i.e. it belongs to the paragraph, not the - //range to which its anchored, which is annoying. -} - -static int -getRand(int modulus) -{ - if (modulus <= 0) - return 0; - return rand() % modulus; -} - -static rtl::OUString -getRandString() -{ - rtl::OUString aText("AAAAA BBBB CCC DD E \n"); - int s = getRand(aText.getLength()); - int j = getRand(aText.getLength() - s); - rtl::OUString aRet(aText.copy(s, j)); - if (!getRand(5)) - aRet += rtl::OUString(sal_Unicode('\n')); -// fprintf (stderr, "rand string '%s'\n", OUStringToOString(aRet, RTL_TEXTENCODING_UTF8).getStr()); - return aRet; -} - -static SwPosition -getRandomPosition(SwDoc *pDoc, int /* nOffset */) -{ - const SwPosition aPos(pDoc->GetNodes().GetEndOfContent()); - sal_uLong nNodes = aPos.nNode.GetNode().GetIndex() - aPos.nNode.GetNode().StartOfSectionIndex(); - sal_uLong n = (rand() * nNodes) / RAND_MAX; - SwPaM pam(aPos); - for (sal_uLong i = 0; i < n; ++i) { - pam.Move(fnMoveBackward, fnGoNode); - } - return *pam.GetPoint(); -} - -void SwDocTest::randomTest() -{ - CPPUNIT_ASSERT_MESSAGE("SwDoc::IsRedlineOn()", !m_pDoc->IsRedlineOn()); - RedlineMode_t modes[] = { - nsRedlineMode_t::REDLINE_ON, - nsRedlineMode_t::REDLINE_SHOW_MASK, - nsRedlineMode_t::REDLINE_NONE, - nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_MASK, - nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE, - nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE | nsRedlineMode_t::REDLINE_SHOW_MASK, - nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT, - nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE - }; - static const char *authors[] = { - "Jim", "Bob", "JimBobina", "Helga", "Gertrude", "Spagna", "Hurtleweed" - }; - - for( sal_uInt16 rlm = 0; rlm < SAL_N_ELEMENTS(modes); rlm++ ) - { - m_pDoc->ClearDoc(); - - // setup redlining - m_pDoc->SetRedlineMode(modes[rlm]); - SW_MOD()->SetRedlineAuthor(rtl::OUString::createFromAscii(authors[0])); - - for( int i = 0; i < 2000; i++ ) - { - SwPaM aPam(m_pDoc->GetNodes()); - SwCursor aCrs(getRandomPosition(m_pDoc, i/20), 0, false); - aCrs.SetMark(); - - switch (getRand (i < 50 ? 3 : 6)) { - // insert ops first - case 0: { - if (!m_pDoc->InsertString(aCrs, getRandString())) { -// fprintf (stderr, "failed to insert string !\n"); - } - break; - } - case 1: - break; - case 2: { // switch author - int a = getRand(SAL_N_ELEMENTS(authors)); - SW_MOD()->SetRedlineAuthor(rtl::OUString::createFromAscii(authors[a])); - break; - } - - // movement / deletion ops later - case 3: // deletion - switch (getRand(6)) { - case 0: - m_pDoc->DelFullPara(aCrs); - break; - case 1: - m_pDoc->DeleteRange(aCrs); - break; - case 2: - m_pDoc->DeleteAndJoin(aCrs, !!getRand(1)); - break; - case 3: - default: - m_pDoc->Overwrite(aCrs, getRandString()); - break; - } - break; - case 4: { // movement - IDocumentContentOperations::SwMoveFlags nFlags = - (IDocumentContentOperations::SwMoveFlags) - (getRand(1) ? // FIXME: puterb this more ? - IDocumentContentOperations::DOC_MOVEDEFAULT : - IDocumentContentOperations::DOC_MOVEALLFLYS | - IDocumentContentOperations::DOC_CREATEUNDOOBJ | - IDocumentContentOperations::DOC_MOVEREDLINES | - IDocumentContentOperations::DOC_NO_DELFRMS); - SwPosition aTo(getRandomPosition(m_pDoc, i/10)); - m_pDoc->MoveRange(aCrs, aTo, nFlags); - break; - } - - case 5: - break; - - // undo / redo ? - default: - break; - } - } - -// Debug / verify the produced document has real content -#if 0 - rtl::OStringBuffer aBuffer("nodes-"); - aBuffer.append(sal_Int32(rlm)); - aBuffer.append(".xml"); - - xmlTextWriterPtr writer; - writer = xmlNewTextWriterFilename( aBuffer.makeStringAndClear().getStr(), 0 ); - xmlTextWriterStartDocument( writer, NULL, NULL, NULL ); - m_pDoc->dumpAsXml(writer); - xmlTextWriterEndDocument( writer ); - xmlFreeTextWriter( writer ); -#endif - } -} - -void SwDocTest::testFdo57938() -{ - SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1); - SwPaM aPaM(aIdx); - - // Insert "atest" and create a fieldmark around "test". - OUString aTest("atest"); - m_pDoc->InsertString(aPaM, aTest); - aPaM.SetMark(); - aPaM.GetPoint()->nContent = 1; - IDocumentMarkAccess* pMarksAccess = m_pDoc->getIDocumentMarkAccess(); - pMarksAccess->makeFieldBookmark(aPaM, "", ODF_COMMENTRANGE); - aPaM.GetPoint()->nContent = 0; - aPaM.GetMark()->nContent = 1; - // The problem was that "a" was considered read-only, so could not be deleted. - CPPUNIT_ASSERT_EQUAL(false, aPaM.HasReadonlySel(false)); -} - -void SwDocTest::setUp() -{ - BootstrapFixture::setUp(); - - SwGlobals::ensure(); - m_pDoc = new SwDoc; - m_xDocShRef = new SwDocShell(m_pDoc, SFX_CREATE_MODE_EMBEDDED); - m_xDocShRef->DoInitNew(0); -} - -void SwDocTest::tearDown() -{ - m_xDocShRef.Clear(); - delete m_pDoc; - - BootstrapFixture::tearDown(); -} - -CPPUNIT_TEST_SUITE_REGISTRATION(SwDocTest); - -CPPUNIT_PLUGIN_IMPLEMENT(); - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/core/uwriter.cxx b/sw/qa/core/uwriter.cxx new file mode 100644 index 000000000000..189a25cf2476 --- /dev/null +++ b/sw/qa/core/uwriter.cxx @@ -0,0 +1,921 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is + * Thorsten Behrens + * Portions created by the Initial Developer are Copyright (C) 2011 the + * Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Thorsten Behrens + * Caolán McNamara + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include "breakit.hxx" +#include "doc.hxx" +#include "docsh.hxx" +#include "docstat.hxx" +#include "docufld.hxx" +#include "fmtanchr.hxx" +#include "init.hxx" +#include "ndtxt.hxx" +#include "shellio.hxx" +#include "shellres.hxx" +#include "swcrsr.hxx" +#include "swscanner.hxx" +#include "swmodule.hxx" +#include "swtypes.hxx" +#include "fmtftn.hxx" +#include "fmtrfmrk.hxx" +#include "fmtfld.hxx" +#include "redline.hxx" +#include "docary.hxx" +#include "modeltoviewhelper.hxx" +#include "scriptinfo.hxx" + +SV_DECL_REF(SwDocShell) +SV_IMPL_REF(SwDocShell) + +using namespace ::com::sun::star; + +/* Implementation of Swdoc-Test class */ + +class SwDocTest : public test::BootstrapFixture +{ +public: + virtual void setUp(); + virtual void tearDown(); + + void randomTest(); + void testPageDescName(); + void testFileNameFields(); + void testDocStat(); + void testModelToViewHelper(); + void testSwScanner(); + void testUserPerceivedCharCount(); + void testGraphicAnchorDeletion(); + void testFdo57938(); + + CPPUNIT_TEST_SUITE(SwDocTest); + CPPUNIT_TEST(randomTest); + CPPUNIT_TEST(testPageDescName); + CPPUNIT_TEST(testFileNameFields); + CPPUNIT_TEST(testDocStat); + CPPUNIT_TEST(testModelToViewHelper); + CPPUNIT_TEST(testSwScanner); + CPPUNIT_TEST(testUserPerceivedCharCount); + CPPUNIT_TEST(testGraphicAnchorDeletion); + CPPUNIT_TEST(testFdo57938); + CPPUNIT_TEST_SUITE_END(); + +private: + SwDoc *m_pDoc; + SwDocShellRef m_xDocShRef; +}; + +void SwDocTest::testPageDescName() +{ + ShellResource aShellResources; + + std::vector aResults; + + //These names must be unique for each different combination, otherwise + //duplicate page description names may exist, which will causes lookup + //by name to be incorrect, and so the corresponding export to .odt + aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::NORMAL_PAGE)); + aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::FIRST_PAGE)); + aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::FOLLOW_PAGE)); + + std::sort(aResults.begin(), aResults.end()); + aResults.erase(std::unique(aResults.begin(), aResults.end()), aResults.end()); + + CPPUNIT_ASSERT_MESSAGE("GetPageDescName results must be unique", aResults.size() == 3); +} + +//See https://bugs.freedesktop.org/show_bug.cgi?id=32463 +void SwDocTest::testFileNameFields() +{ + //Here's a file name with some chars in it that will be %% encoded, when expanding + //SwFileNameFields we want to restore the original readable filename + utl::TempFile aTempFile(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("demo [name]"))); + aTempFile.EnableKillingFile(); + + INetURLObject aTempFileURL(aTempFile.GetURL()); + String sFileURL = aTempFileURL.GetMainURL(INetURLObject::NO_DECODE); + SfxMedium aDstMed(sFileURL, STREAM_STD_READWRITE); + + SfxFilter aFilter( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text")), + rtl::OUString(), 0, 0, rtl::OUString(), 0, rtl::OUString(), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TEXT")), rtl::OUString() ); + aDstMed.SetFilter(&aFilter); + + m_xDocShRef->DoSaveAs(aDstMed); + m_xDocShRef->DoSaveCompleted(&aDstMed); + + const INetURLObject &rUrlObj = m_xDocShRef->GetMedium()->GetURLObject(); + + SwFileNameFieldType aNameField(m_pDoc); + + { + rtl::OUString sResult(aNameField.Expand(FF_NAME)); + rtl::OUString sExpected(rUrlObj.getName(INetURLObject::LAST_SEGMENT, + true,INetURLObject::DECODE_WITH_CHARSET)); + CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected); + } + + { + rtl::OUString sResult(aNameField.Expand(FF_PATHNAME)); + rtl::OUString sExpected(rUrlObj.GetFull()); + CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected); + } + + { + rtl::OUString sResult(aNameField.Expand(FF_PATH)); + INetURLObject aTemp(rUrlObj); + aTemp.removeSegment(); + rtl::OUString sExpected(aTemp.PathToFileName()); + CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected); + } + + { + rtl::OUString sResult(aNameField.Expand(FF_NAME_NOEXT)); + rtl::OUString sExpected(rUrlObj.getName(INetURLObject::LAST_SEGMENT, + true,INetURLObject::DECODE_WITH_CHARSET)); + //Chop off .tmp + sExpected = sExpected.copy(0, sExpected.getLength() - 4); + CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected); + } + + m_xDocShRef->DoInitNew(0); +} + +//See http://lists.freedesktop.org/archives/libreoffice/2011-August/016666.html +//Remove unnecessary parameter to IDocumentStatistics::UpdateDocStat for +//motivation +void SwDocTest::testDocStat() +{ + CPPUNIT_ASSERT_MESSAGE("Expected initial 0 count", m_pDoc->GetDocStat().nChar == 0); + + SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1); + SwPaM aPaM(aIdx); + + rtl::OUString sText(RTL_CONSTASCII_USTRINGPARAM("Hello World")); + m_pDoc->InsertString(aPaM, sText); + + CPPUNIT_ASSERT_MESSAGE("Should still be non-updated 0 count", m_pDoc->GetDocStat().nChar == 0); + + SwDocStat aDocStat = m_pDoc->GetUpdatedDocStat(); + sal_uLong nLen = static_cast(sText.getLength()); + + CPPUNIT_ASSERT_MESSAGE("Should now have updated count", aDocStat.nChar == nLen); + + CPPUNIT_ASSERT_MESSAGE("And cache is updated too", m_pDoc->GetDocStat().nChar == nLen); +} + +//For UI character counts we should follow UAX#29 and display the user +//perceived characters, not the number of codepoints, nor the number of code +//units http://unicode.org/reports/tr29/ +void SwDocTest::testUserPerceivedCharCount() +{ + SwBreakIt *pBreakIter = SwBreakIt::Get(); + + //Grapheme example, two different unicode code-points perceived by the user as a single + //glyph + const sal_Unicode ALEF_QAMATS [] = { 0x05D0, 0x05B8 }; + ::rtl::OUString sALEF_QAMATS(ALEF_QAMATS, SAL_N_ELEMENTS(ALEF_QAMATS)); + sal_Int32 nGraphemeCount = pBreakIter->getGraphemeCount(sALEF_QAMATS); + CPPUNIT_ASSERT_MESSAGE("Grapheme Count should be 1", nGraphemeCount == 1); + + //Surrogate pair example, one single unicode code-point (U+1D11E) + //represented as two code units in UTF-16 + const sal_Unicode GCLEF[] = { 0xD834, 0xDD1E }; + ::rtl::OUString sGCLEF(GCLEF, SAL_N_ELEMENTS(GCLEF)); + sal_Int32 nCount = pBreakIter->getGraphemeCount(sGCLEF); + CPPUNIT_ASSERT_MESSAGE("Surrogate Pair should be counted as single character", nCount == 1); +} + +void SwDocTest::testModelToViewHelper() +{ + SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1); + SwPaM aPaM(aIdx); + + { + SwFmtFtn aFtn; + aFtn.SetNumStr(rtl::OUString("foo")); + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, rtl::OUString("AAAAA BBBBB ")); + SwTxtNode* pTxtNode = aPaM.GetNode()->GetTxtNode(); + xub_StrLen nPos = aPaM.GetPoint()->nContent.GetIndex(); + pTxtNode->InsertItem(aFtn, nPos, nPos); + m_pDoc->InsertString(aPaM, rtl::OUString(" CCCCC ")); + nPos = aPaM.GetPoint()->nContent.GetIndex(); + pTxtNode->InsertItem(aFtn, nPos, nPos); + m_pDoc->InsertString(aPaM, rtl::OUString(" DDDDD")); + CPPUNIT_ASSERT(pTxtNode->GetTxt().Len() == (4*5) + 5 + 2); + + //set start of selection to first B + aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 6); + aPaM.SetMark(); + //set end of selection to last C + aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 14); + //set character attribute hidden on range + SvxCharHiddenItem aHidden(true, RES_CHRATR_HIDDEN); + m_pDoc->InsertPoolItem(aPaM, aHidden, 0 ); + + //turn on red-lining and show changes + m_pDoc->SetRedlineMode(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE|nsRedlineMode_t::REDLINE_SHOW_INSERT); + CPPUNIT_ASSERT_MESSAGE("redlining should be on", m_pDoc->IsRedlineOn()); + CPPUNIT_ASSERT_MESSAGE("redlines should be visible", IDocumentRedlineAccess::IsShowChanges(m_pDoc->GetRedlineMode())); + + //set start of selection to last A + aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 4); + aPaM.SetMark(); + //set end of selection to second last B + aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 9); + m_pDoc->DeleteAndJoin(aPaM); //redline-aware deletion api + + { + ModelToViewHelper aModelToViewHelper(*pTxtNode, PASSTHROUGH); + rtl::OUString sViewText = aModelToViewHelper.getViewText(); + rtl::OUString sModelText = pTxtNode->GetTxt(); + CPPUNIT_ASSERT(sViewText == sModelText); + } + + { + ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS); + rtl::OUString sViewText = aModelToViewHelper.getViewText(); + CPPUNIT_ASSERT(sViewText == "AAAAA BBBBB foo CCCCC foo DDDDD"); + } + + { + ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEINVISIBLE); + rtl::OUString sViewText = aModelToViewHelper.getViewText(); + rtl::OUStringBuffer aBuffer; + aBuffer.append("AAAAA CCCCC "); + aBuffer.append(CH_TXTATR_BREAKWORD); + aBuffer.append(" DDDDD"); + CPPUNIT_ASSERT(sViewText == aBuffer.makeStringAndClear()); + } + + { + ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEREDLINED); + rtl::OUString sViewText = aModelToViewHelper.getViewText(); + rtl::OUStringBuffer aBuffer; + aBuffer.append("AAAABB "); + aBuffer.append(CH_TXTATR_BREAKWORD); + aBuffer.append(" CCCCC "); + aBuffer.append(CH_TXTATR_BREAKWORD); + aBuffer.append(" DDDDD"); + CPPUNIT_ASSERT(sViewText == aBuffer.makeStringAndClear()); + } + + { + ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEINVISIBLE); + rtl::OUString sViewText = aModelToViewHelper.getViewText(); + CPPUNIT_ASSERT(sViewText == "AAAAA CCCCC foo DDDDD"); + } + + { + ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEREDLINED); + rtl::OUString sViewText = aModelToViewHelper.getViewText(); + CPPUNIT_ASSERT(sViewText == "AAAABB foo CCCCC foo DDDDD"); + } + + { + ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEINVISIBLE | HIDEREDLINED); + rtl::OUString sViewText = aModelToViewHelper.getViewText(); + rtl::OUStringBuffer aBuffer; + aBuffer.append("AAAACCCCC "); + aBuffer.append(CH_TXTATR_BREAKWORD); + aBuffer.append(" DDDDD"); + CPPUNIT_ASSERT(sViewText == aBuffer.makeStringAndClear()); + } + + { + ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEINVISIBLE | HIDEREDLINED); + rtl::OUString sViewText = aModelToViewHelper.getViewText(); + CPPUNIT_ASSERT(sViewText == "AAAACCCCC foo DDDDD"); + } + } +} + +void SwDocTest::testSwScanner() +{ + SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1); + SwPaM aPaM(aIdx); + + SwTxtNode* pTxtNode = aPaM.GetNode()->GetTxtNode(); + + CPPUNIT_ASSERT_MESSAGE("Has Text Node", pTxtNode); + + //See https://bugs.freedesktop.org/show_bug.cgi?id=40449 + //See https://bugs.freedesktop.org/show_bug.cgi?id=39365 + //Use a temporary rtl::OUString as the arg, as that's the trouble behind + //fdo#40449 and fdo#39365 + { + SwScanner aScanner(*pTxtNode, + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hello World")), + 0, ModelToViewHelper(), i18n::WordType::DICTIONARY_WORD, 0, + RTL_CONSTASCII_LENGTH("Hello World")); + + bool bFirstOk = aScanner.NextWord(); + CPPUNIT_ASSERT_MESSAGE("First Token", bFirstOk); + const rtl::OUString &rHello = aScanner.GetWord(); + CPPUNIT_ASSERT_MESSAGE("Should be Hello", + rHello.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Hello"))); + + bool bSecondOk = aScanner.NextWord(); + CPPUNIT_ASSERT_MESSAGE("Second Token", bSecondOk); + const rtl::OUString &rWorld = aScanner.GetWord(); + CPPUNIT_ASSERT_MESSAGE("Should be World", + rWorld.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("World"))); + } + + //See https://www.libreoffice.org/bugzilla/show_bug.cgi?id=45271 + { + const sal_Unicode IDEOGRAPHICFULLSTOP_D[] = { 0x3002, 'D' }; + + m_pDoc->InsertString(aPaM, rtl::OUString(IDEOGRAPHICFULLSTOP_D, + SAL_N_ELEMENTS(IDEOGRAPHICFULLSTOP_D))); + + SvxLanguageItem aCJKLangItem( LANGUAGE_CHINESE_SIMPLIFIED, RES_CHRATR_CJK_LANGUAGE ); + SvxLanguageItem aWestLangItem( LANGUAGE_ENGLISH_US, RES_CHRATR_LANGUAGE ); + m_pDoc->InsertPoolItem(aPaM, aCJKLangItem, 0 ); + m_pDoc->InsertPoolItem(aPaM, aWestLangItem, 0 ); + + SwDocStat aDocStat; + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(IDEOGRAPHICFULLSTOP_D)); + + CPPUNIT_ASSERT_MESSAGE("Should be 2", aDocStat.nChar == 2); + CPPUNIT_ASSERT_MESSAGE("Should be 2", aDocStat.nCharExcludingSpaces == 2); + } + { + const sal_Unicode test[] = + { + 0x3053, 0x306E, 0x65E5, 0x672C, 0x8A9E, 0x306F, 0x6B63, 0x3057, + 0x304F, 0x6570, 0x3048, 0x3089, 0x308C, 0x308B, 0x3067, 0x3057, + 0x3087, 0x3046, 0x304B, 0x3002, 0x0041, 0x006E, 0x0064, 0x0020, + 0x006C, 0x0065, 0x0074, 0x0027, 0x0073, 0x0020, 0x0074, 0x0068, + 0x0072, 0x006F, 0x0077, 0x0020, 0x0073, 0x006F, 0x006D, 0x0065, + 0x0020, 0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068, + 0x0020, 0x0069, 0x006E, 0x0020, 0x0074, 0x006F, 0x0020, 0x006D, + 0x0061, 0x006B, 0x0065, 0x0020, 0x0069, 0x0074, 0x0020, 0x0069, + 0x006E, 0x0074, 0x0065, 0x0072, 0x0065, 0x0073, 0x0074, 0x0069, + 0x006E, 0x0067, 0x002E, 0x0020, 0x0020, 0x305D, 0x3057, 0x3066, + 0x3001, 0x307E, 0x305F, 0x65E5, 0x672C, 0x8A9E, 0x3000, 0x3000, + 0x3067, 0x3082, 0x4ECA, 0x56DE, 0x306F, 0x7A7A, 0x767D, 0x3092, + 0x3000, 0x3000, 0x5165, 0x308C, 0x307E, 0x3057, 0x305F, 0x3002, + 0x0020, 0x0020, 0x0053, 0x006F, 0x0020, 0x0068, 0x006F, 0x0077, + 0x0020, 0x0064, 0x006F, 0x0065, 0x0073, 0x0020, 0x0074, 0x0068, + 0x0069, 0x0073, 0x0020, 0x0064, 0x006F, 0x003F, 0x0020, 0x0020 + }; + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, rtl::OUString(test, + SAL_N_ELEMENTS(test))); + + SvxLanguageItem aCJKLangItem( LANGUAGE_JAPANESE, RES_CHRATR_CJK_LANGUAGE ); + SvxLanguageItem aWestLangItem( LANGUAGE_ENGLISH_US, RES_CHRATR_LANGUAGE ); + m_pDoc->InsertPoolItem(aPaM, aCJKLangItem, 0 ); + m_pDoc->InsertPoolItem(aPaM, aWestLangItem, 0 ); + + SwDocStat aDocStat; + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(test)); + CPPUNIT_ASSERT_MESSAGE("58 words", aDocStat.nWord == 58); + CPPUNIT_ASSERT_MESSAGE("43 Asian characters and Korean syllables", aDocStat.nAsianWord == 43); + CPPUNIT_ASSERT_MESSAGE("105 non-whitespace chars", aDocStat.nCharExcludingSpaces == 105); + CPPUNIT_ASSERT_MESSAGE("128 characters", aDocStat.nChar == 128); + } + + //See https://issues.apache.org/ooo/show_bug.cgi?id=89042 + //See https://bugs.freedesktop.org/show_bug.cgi?id=53399 + { + SwDocStat aDocStat; + + const sal_Unicode aShouldBeThree[] = { + 0x0053, 0x0068, 0x006F, 0x0075, 0x006C, 0x0064, 0x0020, + 0x2018, 0x0062, 0x0065, 0x0020, 0x0074, 0x0068, 0x0072, + 0x0065, 0x0065, 0x2019 + }; + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, rtl::OUString(aShouldBeThree, SAL_N_ELEMENTS(aShouldBeThree))); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(aShouldBeThree)); + CPPUNIT_ASSERT_MESSAGE("Should be 3", aDocStat.nWord == 3); + + const sal_Unicode aShouldBeFive[] = { + // f r e n c h space + 0x0046, 0x0072, 0x0065, 0x006E, 0x0063, 0x0068, 0x0020, + // << nbsp s a v o i + 0x00AB, 0x00A0, 0x0073, 0x0061, 0x0076, 0x006F, 0x0069, + // r nnbsp c a l c u + 0x0072, 0x202f, 0x0063, 0x0061, 0x006C, 0x0063, 0x0075, + // l e r idspace >> + 0x006C, 0x0065, 0x0072, 0x3000, 0x00BB + }; + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, rtl::OUString(aShouldBeFive, SAL_N_ELEMENTS(aShouldBeFive))); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + aDocStat.Reset(); + pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(aShouldBeFive)); + CPPUNIT_ASSERT_MESSAGE("Should be 5", aDocStat.nWord == 5); + } + + //See https://bugs.freedesktop.org/show_bug.cgi?id=49629 + { + SwDocStat aDocStat; + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, rtl::OUString("Apple")); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + xub_StrLen nPos = aPaM.GetPoint()->nContent.GetIndex(); + SwFmtFtn aFtn; + aFtn.SetNumStr(rtl::OUString("banana")); + SwTxtAttr* pTA = pTxtNode->InsertItem(aFtn, nPos, nPos); + CPPUNIT_ASSERT(pTA); + CPPUNIT_ASSERT(pTxtNode->Len() == 6); //Apple + 0x02 + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 1); + CPPUNIT_ASSERT_MESSAGE("footnote should be expanded", aDocStat.nChar == 11); + + xub_StrLen nNextPos = aPaM.GetPoint()->nContent.GetIndex(); + CPPUNIT_ASSERT(nNextPos == nPos+1); + SwFmtRefMark aRef(rtl::OUString("refmark")); + pTA = pTxtNode->InsertItem(aRef, nNextPos, nNextPos); + CPPUNIT_ASSERT(pTA); + + aDocStat.Reset(); + pTxtNode->SetWordCountDirty(true); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 1); + CPPUNIT_ASSERT_MESSAGE("refmark anchor should not be counted", aDocStat.nChar == 11); + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, rtl::OUString("Apple")); + + DateTime aDate(DateTime::SYSTEM); + SwPostItField aPostIt( + (SwPostItFieldType*)m_pDoc->GetSysFldType(RES_POSTITFLD), rtl::OUString("An Author"), + rtl::OUString("Some Text"), rtl::OUString("Initials"), OUString("Name"), aDate ); + m_pDoc->InsertPoolItem(aPaM, SwFmtFld(aPostIt), 0); + + m_pDoc->InsertString(aPaM, rtl::OUString("Apple")); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + aDocStat.Reset(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 1); + CPPUNIT_ASSERT_MESSAGE("postit anchor should effectively not exist", aDocStat.nChar == 10); + CPPUNIT_ASSERT(pTxtNode->Len() == 11); + + aDocStat.Reset(); + } + + //See https://bugs.freedesktop.org/show_bug.cgi?id=46757 + { + SwDocStat aDocStat; + + const char aString[] = "Lorem ipsum"; + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, rtl::OUString(aString)); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast(2)); + + //turn on red-lining and show changes + m_pDoc->SetRedlineMode(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE|nsRedlineMode_t::REDLINE_SHOW_INSERT); + CPPUNIT_ASSERT_MESSAGE("redlining should be on", m_pDoc->IsRedlineOn()); + CPPUNIT_ASSERT_MESSAGE("redlines should be visible", IDocumentRedlineAccess::IsShowChanges(m_pDoc->GetRedlineMode())); + + //delete everything except the first word + aPaM.SetMark(); //set start of selection to current pos + aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 5); //set end of selection to fifth char of current node + m_pDoc->DeleteAndJoin(aPaM); //redline-aware deletion api + CPPUNIT_ASSERT_MESSAGE("real underlying text should be the same", pTxtNode->GetTxt().EqualsAscii(aString)); + + aDocStat.Reset(); + pTxtNode->SetWordCountDirty(true); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //but word-counting the text should only count the non-deleted text + CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast(1)); + + pTxtNode->SetWordCountDirty(true); + + //keep red-lining on but hide changes + m_pDoc->SetRedlineMode(nsRedlineMode_t::REDLINE_ON); + CPPUNIT_ASSERT_MESSAGE("redlining should be still on", m_pDoc->IsRedlineOn()); + CPPUNIT_ASSERT_MESSAGE("redlines should be invisible", !IDocumentRedlineAccess::IsShowChanges(m_pDoc->GetRedlineMode())); + + aDocStat.Reset(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //but word-counting the text should only count the non-deleted text + CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast(1)); + + rtl::OUString sLorem = pTxtNode->GetTxt(); + CPPUNIT_ASSERT(sLorem == "Lorem"); + + const SwRedlineTbl& rTbl = m_pDoc->GetRedlineTbl(); + + SwNodes& rNds = m_pDoc->GetNodes(); + CPPUNIT_ASSERT(rTbl.size() == 1); + + SwNodeIndex* pNodeIdx = rTbl[0]->GetContentIdx(); + CPPUNIT_ASSERT(pNodeIdx); + + pTxtNode = rNds[ pNodeIdx->GetIndex() + 1 ]->GetTxtNode(); //first deleted txtnode + CPPUNIT_ASSERT(pTxtNode); + + rtl::OUString sIpsum = pTxtNode->GetTxt(); + CPPUNIT_ASSERT(sIpsum == " ipsum"); + + aDocStat.Reset(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //word-counting the text should only count the non-deleted text, and this whole chunk should be ignored + CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast(0)); + CPPUNIT_ASSERT_EQUAL(aDocStat.nChar, static_cast(0)); + } + + //See https://bugs.freedesktop.org/show_bug.cgi?id=38983 + { + SwDocStat aDocStat; + + rtl::OUString sTemplate("ThisXis a test."); + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, sTemplate.replace('X', ' ')); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 4 && + aDocStat.nCharExcludingSpaces == 12 && + aDocStat.nChar == 15); + aDocStat.Reset(); + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, sTemplate.replaceAll(rtl::OUString('X'), rtl::OUString(" = "))); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 5 && + aDocStat.nCharExcludingSpaces == 13 && + aDocStat.nChar == 17); + aDocStat.Reset(); + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, sTemplate.replaceAll(rtl::OUString('X'), rtl::OUString(" _ "))); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 5 && + aDocStat.nCharExcludingSpaces == 13 && + aDocStat.nChar == 17); + aDocStat.Reset(); + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, sTemplate.replaceAll(rtl::OUString('X'), rtl::OUString(" -- "))); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 5 && + aDocStat.nCharExcludingSpaces == 14 && + aDocStat.nChar == 18); + aDocStat.Reset(); + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, sTemplate.replace('X', '_')); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 3 && + aDocStat.nCharExcludingSpaces == 13 && + aDocStat.nChar == 15); + aDocStat.Reset(); + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, sTemplate.replace('X', '-')); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 3 && + aDocStat.nCharExcludingSpaces == 13 && + aDocStat.nChar == 15); + aDocStat.Reset(); + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2012)); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 3 && + aDocStat.nCharExcludingSpaces == 13 && + aDocStat.nChar == 15); + aDocStat.Reset(); + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2015)); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 3 && + aDocStat.nCharExcludingSpaces == 13 && + aDocStat.nChar == 15); + aDocStat.Reset(); + + //But default configuration should, msword-alike treak emdash + //and endash as word seperators for word-counting + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2013)); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 4 && + aDocStat.nCharExcludingSpaces == 13 && + aDocStat.nChar == 15); + aDocStat.Reset(); + + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, sTemplate.replace('X', 0x2014)); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 4 && + aDocStat.nCharExcludingSpaces == 13 && + aDocStat.nChar == 15); + aDocStat.Reset(); + + const sal_Unicode aChunk[] = {' ', 0x2013, ' '}; + rtl::OUString sChunk(aChunk, SAL_N_ELEMENTS(aChunk)); + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + m_pDoc->InsertString(aPaM, sTemplate.replaceAll(rtl::OUString('X'), sChunk)); + pTxtNode = aPaM.GetNode()->GetTxtNode(); + pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); + CPPUNIT_ASSERT(aDocStat.nWord == 4 && + aDocStat.nCharExcludingSpaces == 13 && + aDocStat.nChar == 17); + aDocStat.Reset(); + } +} + +//See https://bugs.freedesktop.org/show_bug.cgi?id=40599 +void SwDocTest::testGraphicAnchorDeletion() +{ + CPPUNIT_ASSERT_MESSAGE("Expected initial 0 count", m_pDoc->GetDocStat().nChar == 0); + + SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1); + SwPaM aPaM(aIdx); + + m_pDoc->InsertString(aPaM, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Paragraph 1"))); + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + + m_pDoc->InsertString(aPaM, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("graphic anchor>><nNode; + m_pDoc->AppendTxtNode(*aPaM.GetPoint()); + + m_pDoc->InsertString(aPaM, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Paragraph 3"))); + + aPaM.GetPoint()->nNode = nPara2; + aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), RTL_CONSTASCII_LENGTH("graphic anchor>>")); + + //Insert a graphic at X of >>X<< in paragraph 2 + SfxItemSet aFlySet(m_pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1); + SwFmtAnchor aAnchor(FLY_AS_CHAR); + aAnchor.SetAnchor(aPaM.GetPoint()); + aFlySet.Put(aAnchor); + SwFlyFrmFmt *pFrame = m_pDoc->Insert(aPaM, rtl::OUString(), rtl::OUString(), NULL, &aFlySet, NULL, NULL); + CPPUNIT_ASSERT_MESSAGE("Expected frame", pFrame != NULL); + + CPPUNIT_ASSERT_MESSAGE("Should be 1 graphic", m_pDoc->GetFlyCount(FLYCNTTYPE_GRF) == 1); + + //Delete >X< + aPaM.GetPoint()->nNode = nPara2; + aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), + RTL_CONSTASCII_LENGTH("graphic anchor>><")+1); + aPaM.SetMark(); + aPaM.GetPoint()->nNode = nPara2; + aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), RTL_CONSTASCII_LENGTH("graphic anchor>")); + m_pDoc->DeleteRange(aPaM); + +#ifdef DEBUG_AS_HTML + { + SvFileStream aPasteDebug(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "cppunitDEBUG.html")), STREAM_WRITE|STREAM_TRUNC); + WriterRef xWrt; + GetHTMLWriter( String(), String(), xWrt ); + SwWriter aDbgWrt( aPasteDebug, *m_pDoc ); + aDbgWrt.Write( xWrt ); + } +#endif + + CPPUNIT_ASSERT_MESSAGE("Should be 0 graphics", m_pDoc->GetFlyCount(FLYCNTTYPE_GRF) == 0); + + //Now, if instead we swap FLY_AS_CHAR (inline graphic) to FLY_AT_CHAR (anchored to character) + //and repeat the above, graphic is *not* deleted, i.e. it belongs to the paragraph, not the + //range to which its anchored, which is annoying. +} + +static int +getRand(int modulus) +{ + if (modulus <= 0) + return 0; + return rand() % modulus; +} + +static rtl::OUString +getRandString() +{ + rtl::OUString aText("AAAAA BBBB CCC DD E \n"); + int s = getRand(aText.getLength()); + int j = getRand(aText.getLength() - s); + rtl::OUString aRet(aText.copy(s, j)); + if (!getRand(5)) + aRet += rtl::OUString(sal_Unicode('\n')); +// fprintf (stderr, "rand string '%s'\n", OUStringToOString(aRet, RTL_TEXTENCODING_UTF8).getStr()); + return aRet; +} + +static SwPosition +getRandomPosition(SwDoc *pDoc, int /* nOffset */) +{ + const SwPosition aPos(pDoc->GetNodes().GetEndOfContent()); + sal_uLong nNodes = aPos.nNode.GetNode().GetIndex() - aPos.nNode.GetNode().StartOfSectionIndex(); + sal_uLong n = (rand() * nNodes) / RAND_MAX; + SwPaM pam(aPos); + for (sal_uLong i = 0; i < n; ++i) { + pam.Move(fnMoveBackward, fnGoNode); + } + return *pam.GetPoint(); +} + +void SwDocTest::randomTest() +{ + CPPUNIT_ASSERT_MESSAGE("SwDoc::IsRedlineOn()", !m_pDoc->IsRedlineOn()); + RedlineMode_t modes[] = { + nsRedlineMode_t::REDLINE_ON, + nsRedlineMode_t::REDLINE_SHOW_MASK, + nsRedlineMode_t::REDLINE_NONE, + nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_MASK, + nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE, + nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE | nsRedlineMode_t::REDLINE_SHOW_MASK, + nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT, + nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE + }; + static const char *authors[] = { + "Jim", "Bob", "JimBobina", "Helga", "Gertrude", "Spagna", "Hurtleweed" + }; + + for( sal_uInt16 rlm = 0; rlm < SAL_N_ELEMENTS(modes); rlm++ ) + { + m_pDoc->ClearDoc(); + + // setup redlining + m_pDoc->SetRedlineMode(modes[rlm]); + SW_MOD()->SetRedlineAuthor(rtl::OUString::createFromAscii(authors[0])); + + for( int i = 0; i < 2000; i++ ) + { + SwPaM aPam(m_pDoc->GetNodes()); + SwCursor aCrs(getRandomPosition(m_pDoc, i/20), 0, false); + aCrs.SetMark(); + + switch (getRand (i < 50 ? 3 : 6)) { + // insert ops first + case 0: { + if (!m_pDoc->InsertString(aCrs, getRandString())) { +// fprintf (stderr, "failed to insert string !\n"); + } + break; + } + case 1: + break; + case 2: { // switch author + int a = getRand(SAL_N_ELEMENTS(authors)); + SW_MOD()->SetRedlineAuthor(rtl::OUString::createFromAscii(authors[a])); + break; + } + + // movement / deletion ops later + case 3: // deletion + switch (getRand(6)) { + case 0: + m_pDoc->DelFullPara(aCrs); + break; + case 1: + m_pDoc->DeleteRange(aCrs); + break; + case 2: + m_pDoc->DeleteAndJoin(aCrs, !!getRand(1)); + break; + case 3: + default: + m_pDoc->Overwrite(aCrs, getRandString()); + break; + } + break; + case 4: { // movement + IDocumentContentOperations::SwMoveFlags nFlags = + (IDocumentContentOperations::SwMoveFlags) + (getRand(1) ? // FIXME: puterb this more ? + IDocumentContentOperations::DOC_MOVEDEFAULT : + IDocumentContentOperations::DOC_MOVEALLFLYS | + IDocumentContentOperations::DOC_CREATEUNDOOBJ | + IDocumentContentOperations::DOC_MOVEREDLINES | + IDocumentContentOperations::DOC_NO_DELFRMS); + SwPosition aTo(getRandomPosition(m_pDoc, i/10)); + m_pDoc->MoveRange(aCrs, aTo, nFlags); + break; + } + + case 5: + break; + + // undo / redo ? + default: + break; + } + } + +// Debug / verify the produced document has real content +#if 0 + rtl::OStringBuffer aBuffer("nodes-"); + aBuffer.append(sal_Int32(rlm)); + aBuffer.append(".xml"); + + xmlTextWriterPtr writer; + writer = xmlNewTextWriterFilename( aBuffer.makeStringAndClear().getStr(), 0 ); + xmlTextWriterStartDocument( writer, NULL, NULL, NULL ); + m_pDoc->dumpAsXml(writer); + xmlTextWriterEndDocument( writer ); + xmlFreeTextWriter( writer ); +#endif + } +} + +void SwDocTest::testFdo57938() +{ + SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1); + SwPaM aPaM(aIdx); + + // Insert "atest" and create a fieldmark around "test". + OUString aTest("atest"); + m_pDoc->InsertString(aPaM, aTest); + aPaM.SetMark(); + aPaM.GetPoint()->nContent = 1; + IDocumentMarkAccess* pMarksAccess = m_pDoc->getIDocumentMarkAccess(); + pMarksAccess->makeFieldBookmark(aPaM, "", ODF_COMMENTRANGE); + aPaM.GetPoint()->nContent = 0; + aPaM.GetMark()->nContent = 1; + // The problem was that "a" was considered read-only, so could not be deleted. + CPPUNIT_ASSERT_EQUAL(false, aPaM.HasReadonlySel(false)); +} + +void SwDocTest::setUp() +{ + BootstrapFixture::setUp(); + + SwGlobals::ensure(); + m_pDoc = new SwDoc; + m_xDocShRef = new SwDocShell(m_pDoc, SFX_CREATE_MODE_EMBEDDED); + m_xDocShRef->DoInitNew(0); +} + +void SwDocTest::tearDown() +{ + m_xDocShRef.Clear(); + delete m_pDoc; + + BootstrapFixture::tearDown(); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(SwDocTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit