summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editeng/CppunitTest_editeng_editeng.mk69
-rw-r--r--editeng/Module_editeng.mk1
-rw-r--r--editeng/qa/editeng/editeng.cxx101
-rw-r--r--editeng/source/editeng/impedit.hxx2
-rw-r--r--editeng/source/editeng/impedit2.cxx2
-rw-r--r--editeng/source/editeng/impedit4.cxx54
6 files changed, 225 insertions, 4 deletions
diff --git a/editeng/CppunitTest_editeng_editeng.mk b/editeng/CppunitTest_editeng_editeng.mk
new file mode 100644
index 000000000000..38cbc9543db6
--- /dev/null
+++ b/editeng/CppunitTest_editeng_editeng.mk
@@ -0,0 +1,69 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,editeng_editeng))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,editeng_editeng, \
+ editeng/qa/editeng/editeng \
+))
+
+$(eval $(call gb_CppunitTest_use_library_objects,editeng_editeng,editeng))
+
+$(eval $(call gb_CppunitTest_use_libraries,editeng_editeng, \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ docmodel \
+ i18nlangtag \
+ i18nutil \
+ lng \
+ sal \
+ salhelper \
+ sax \
+ sot \
+ sfx \
+ svl \
+ svt \
+ test \
+ tk \
+ tl \
+ ucbhelper \
+ unotest \
+ utl \
+ vcl \
+ xo \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,editeng_editeng,\
+ boost_headers \
+ icuuc \
+ libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_set_include,editeng_editeng,\
+ -I$(SRCDIR)/editeng/inc \
+ -I$(SRCDIR)/editeng/source/editeng \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,editeng_editeng))
+
+$(eval $(call gb_CppunitTest_use_ure,editeng_editeng))
+$(eval $(call gb_CppunitTest_use_vcl,editeng_editeng))
+
+$(eval $(call gb_CppunitTest_use_rdb,editeng_editeng,services))
+
+$(eval $(call gb_CppunitTest_use_configuration,editeng_editeng))
+
+$(eval $(call gb_CppunitTest_use_more_fonts,editeng_editeng))
+
+# vim: set noet sw=4 ts=4:
diff --git a/editeng/Module_editeng.mk b/editeng/Module_editeng.mk
index 6fedbcb6043e..fca6e8426c4e 100644
--- a/editeng/Module_editeng.mk
+++ b/editeng/Module_editeng.mk
@@ -31,6 +31,7 @@ $(eval $(call gb_Module_add_l10n_targets,editeng,\
$(eval $(call gb_Module_add_check_targets,editeng,\
$(if $(and $(filter $(COM),MSC),$(MERGELIBS)),, \
+ CppunitTest_editeng_editeng \
CppunitTest_editeng_core) \
CppunitTest_editeng_borderline \
CppunitTest_editeng_lookuptree \
diff --git a/editeng/qa/editeng/editeng.cxx b/editeng/qa/editeng/editeng.cxx
new file mode 100644
index 000000000000..5c1f23e7e389
--- /dev/null
+++ b/editeng/qa/editeng/editeng.cxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+
+#include <memory>
+
+#include <editeng/editeng.hxx>
+#include <sfx2/app.hxx>
+#include <svtools/parrtf.hxx>
+#include <svtools/rtftoken.h>
+
+#include <editdoc.hxx>
+#include <eeobj.hxx>
+
+using namespace com::sun::star;
+
+namespace
+{
+/// Covers editeng/source/editeng/ fixes.
+class Test : public test::BootstrapFixture
+{
+public:
+ Test() {}
+
+ void setUp() override
+ {
+ test::BootstrapFixture::setUp();
+ mpItemPool = new EditEngineItemPool();
+ SfxApplication::GetOrCreate();
+ }
+
+ void tearDown() override
+ {
+ mpItemPool.clear();
+ test::BootstrapFixture::tearDown();
+ }
+
+protected:
+ rtl::Reference<EditEngineItemPool> mpItemPool;
+};
+
+/// RTF parser that counts the styles in the document.
+class StyleCounter : public SvRTFParser
+{
+public:
+ StyleCounter(SvStream& rStream);
+ void NextToken(int nToken) override;
+
+ int m_nStyles = 0;
+};
+
+StyleCounter::StyleCounter(SvStream& rStream)
+ : SvRTFParser(rStream)
+{
+}
+
+void StyleCounter::NextToken(int nToken)
+{
+ if (nToken == RTF_S)
+ {
+ ++m_nStyles;
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testRTFStyleExport)
+{
+ // Given a document with an unreferenced style:
+ EditEngine aEditEngine(mpItemPool.get());
+ rtl::Reference<SfxStyleSheetPool> xStyles(new SfxStyleSheetPool(*mpItemPool));
+ xStyles->Make("mystyle", SfxStyleFamily::Para);
+ aEditEngine.SetStyleSheetPool(xStyles.get());
+ OUString aText = u"mytest"_ustr;
+ aEditEngine.SetText(aText);
+
+ // When copying a word from that document:
+ uno::Reference<datatransfer::XTransferable> xData
+ = aEditEngine.CreateTransferable(ESelection(0, 0, 0, aText.getLength()));
+
+ // Then make sure the RTF result doesn't contain the style:
+ auto pData = dynamic_cast<EditDataObject*>(xData.get());
+ SvMemoryStream& rStream = pData->GetRTFStream();
+ tools::SvRef<StyleCounter> xReader(new StyleCounter(rStream));
+ CPPUNIT_ASSERT(xReader->CallParser() != SvParserState::Error);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 0
+ // - Actual : 1
+ // i.e. unreferenced paragraph styles were exported.
+ CPPUNIT_ASSERT_EQUAL(0, xReader->m_nStyles);
+}
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index a1086a8cab93..9f465f4d9d5d 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -770,7 +770,7 @@ private:
EditPaM ReadXML( SvStream& rInput, EditSelection aSel );
EditPaM ReadHTML( SvStream& rInput, const OUString& rBaseURL, EditSelection aSel, SvKeyValueIterator* pHTTPHeaderAttrs );
ErrCode WriteText( SvStream& rOutput, EditSelection aSel );
- ErrCode WriteRTF( SvStream& rOutput, EditSelection aSel );
+ ErrCode WriteRTF( SvStream& rOutput, EditSelection aSel, bool bClipboard );
void WriteXML(SvStream& rOutput, const EditSelection& rSel);
void WriteItemAsRTF( const SfxPoolItem& rItem, SvStream& rOutput, sal_Int32 nPara, sal_Int32 nPos,
diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx
index 83c495072ab8..61c37b00d96f 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -3951,7 +3951,7 @@ uno::Reference< datatransfer::XTransferable > ImpEditEngine::CreateTransferable(
pDataObj->GetString() = convertLineEnd(GetSelected(aSelection), GetSystemLineEnd()); // System specific
- WriteRTF( pDataObj->GetRTFStream(), aSelection );
+ WriteRTF( pDataObj->GetRTFStream(), aSelection, /*bClipboard=*/true );
pDataObj->GetRTFStream().Seek( 0 );
WriteXML( pDataObj->GetODFStream(), aSelection );
diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx
index 5b72524270b8..13f13b6fe491 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -77,6 +77,7 @@
#include <memory>
#include <unordered_map>
#include <vector>
+#include <set>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
@@ -206,7 +207,7 @@ void ImpEditEngine::Write(SvStream& rOutput, EETextFormat eFormat, const EditSel
if ( eFormat == EETextFormat::Text )
WriteText( rOutput, rSel );
else if ( eFormat == EETextFormat::Rtf )
- WriteRTF( rOutput, rSel );
+ WriteRTF( rOutput, rSel, /*bClipboard=*/false );
else if ( eFormat == EETextFormat::Xml )
WriteXML( rOutput, rSel );
else if ( eFormat == EETextFormat::Html )
@@ -291,7 +292,7 @@ void ImpEditEngine::WriteXML(SvStream& rOutput, const EditSelection& rSel)
SvxWriteXML( *GetEditEnginePtr(), rOutput, aESel );
}
-ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, EditSelection aSel )
+ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, EditSelection aSel, bool bClipboard )
{
assert( IsUpdateLayout() && "WriteRTF for UpdateMode = sal_False!" );
CheckIdleFormatter();
@@ -456,6 +457,50 @@ ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, EditSelection aSel )
nId++;
}
+ // Collect used paragraph styles when copying to the clipboard.
+ std::set<SfxStyleSheetBase*> aUsedParagraphStyles;
+ if (bClipboard)
+ {
+ for (sal_Int32 nNode = nStartNode; nNode <= nEndNode; nNode++)
+ {
+ ContentNode* pNode = maEditDoc.GetObject(nNode);
+ if (!pNode)
+ {
+ continue;
+ }
+
+ SfxStyleSheet* pParaStyle = pNode->GetStyleSheet();
+ if (!pParaStyle)
+ {
+ continue;
+ }
+
+ aUsedParagraphStyles.insert(pParaStyle);
+
+ const OUString& rParent = pParaStyle->GetParent();
+ if (!rParent.isEmpty())
+ {
+ auto pParent = static_cast<SfxStyleSheet*>(
+ GetStyleSheetPool()->Find(rParent, pParaStyle->GetFamily()));
+ if (pParent)
+ {
+ aUsedParagraphStyles.insert(pParent);
+ }
+ }
+
+ const OUString& rFollow = pParaStyle->GetFollow();
+ if (!rFollow.isEmpty())
+ {
+ auto pFollow = static_cast<SfxStyleSheet*>(
+ GetStyleSheetPool()->Find(rFollow, pParaStyle->GetFamily()));
+ if (pFollow)
+ {
+ aUsedParagraphStyles.insert(pFollow);
+ }
+ }
+ }
+ }
+
if ( aSSSIterator->Count() )
{
@@ -465,6 +510,11 @@ ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, EditSelection aSel )
for ( SfxStyleSheetBase* pStyle = aSSSIterator->First(); pStyle;
pStyle = aSSSIterator->Next() )
{
+ if (bClipboard && !aUsedParagraphStyles.contains(pStyle))
+ {
+ // Don't write unused paragraph styles in the clipboard case.
+ continue;
+ }
rOutput << endl;
rOutput.WriteChar( '{' ).WriteOString( OOO_STRING_SVTOOLS_RTF_S );