[Libreoffice-commits] core.git: sw/CppunitTest_sw_swdoc_test.mk sw/CppunitTest_sw_uwriter.mk sw/Module_sw.mk sw/qa
Miklos Vajna
vmiklos at suse.cz
Sun Feb 3 03:42:29 PST 2013
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(-)
New commits:
commit c8956344af6d5ffd443b44808f34841e70ffaac0
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Sun Feb 3 12:39:21 2013 +0100
sw: sw_swdoc_test -> sw_uwriter
To be consistent to sc_ucalc and sd_uimpress.
Change-Id: Id6b09bacdf19fb7c524f11352ba81cd630535a74
diff --git a/sw/CppunitTest_sw_swdoc_test.mk b/sw/CppunitTest_sw_swdoc_test.mk
deleted file mode 100644
index 0be24f3..0000000
--- 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 <caolanm at redhat.com>
-# (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 0000000..4f25f5c
--- /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 <caolanm at redhat.com>
+# (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 6abd321..d4ea0ac 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 189a25c..0000000
--- 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 <tbehrens at novell.com>
- * Portions created by the Initial Developer are Copyright (C) 2011 the
- * Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Thorsten Behrens <tbehrens at novell.com>
- * Caolán McNamara <caolanm at redhat.com>
- *
- * 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 <sal/config.h>
-#include <test/bootstrapfixture.hxx>
-
-#include <rtl/strbuf.hxx>
-#include <osl/file.hxx>
-
-#include <tools/urlobj.hxx>
-#include <unotools/tempfile.hxx>
-
-#include <editeng/langitem.hxx>
-#include <editeng/charhiddenitem.hxx>
-
-#include <sfx2/app.hxx>
-#include <sfx2/docfilt.hxx>
-#include <sfx2/docfile.hxx>
-#include <sfx2/sfxmodelfactory.hxx>
-
-#include <xmloff/odffields.hxx>
-
-#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<rtl::OUString> 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<sal_uLong>(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<sal_uLong>(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<sal_uLong>(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<sal_uLong>(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<sal_uLong>(0));
- CPPUNIT_ASSERT_EQUAL(aDocStat.nChar, static_cast<sal_uLong>(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>><<graphic anchor")));
- SwNodeIndex nPara2 = aPaM.GetPoint()->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 0000000..189a25c
--- /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 <tbehrens at novell.com>
+ * Portions created by the Initial Developer are Copyright (C) 2011 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Thorsten Behrens <tbehrens at novell.com>
+ * Caolán McNamara <caolanm at redhat.com>
+ *
+ * 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 <sal/config.h>
+#include <test/bootstrapfixture.hxx>
+
+#include <rtl/strbuf.hxx>
+#include <osl/file.hxx>
+
+#include <tools/urlobj.hxx>
+#include <unotools/tempfile.hxx>
+
+#include <editeng/langitem.hxx>
+#include <editeng/charhiddenitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/sfxmodelfactory.hxx>
+
+#include <xmloff/odffields.hxx>
+
+#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<rtl::OUString> 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<sal_uLong>(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<sal_uLong>(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<sal_uLong>(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<sal_uLong>(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<sal_uLong>(0));
+ CPPUNIT_ASSERT_EQUAL(aDocStat.nChar, static_cast<sal_uLong>(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>><<graphic anchor")));
+ SwNodeIndex nPara2 = aPaM.GetPoint()->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: */
More information about the Libreoffice-commits
mailing list