diff --git a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng index a9c923703e0f..7b0ce565ab5e 100644 --- a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng +++ b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng @@ -4160,7 +4160,7 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. - + @@ -4171,7 +4171,7 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. - + diff --git a/sw/CppunitTest_sw_core_unocore.mk b/sw/CppunitTest_sw_core_unocore.mk index 43fb58bf4fe1..abdad82fa74b 100644 --- a/sw/CppunitTest_sw_core_unocore.mk +++ b/sw/CppunitTest_sw_core_unocore.mk @@ -15,6 +15,7 @@ $(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_core_unocore)) $(eval $(call gb_CppunitTest_add_exception_objects,sw_core_unocore, \ sw/qa/core/unocore/unocore \ + sw/qa/core/unocore/unocrsrhelper \ )) # note: this links msword only for the reason to have an order dependency, diff --git a/sw/inc/unocrsrhelper.hxx b/sw/inc/unocrsrhelper.hxx index 270b2a69d6dd..0eda90fdc7c5 100644 --- a/sw/inc/unocrsrhelper.hxx +++ b/sw/inc/unocrsrhelper.hxx @@ -242,6 +242,8 @@ namespace SwUnoCursorHelper css::uno::Reference CreateFlatParagraphIterator(SwDoc &, sal_Int32, bool); + void SetCharStyle(SwDoc& rDoc, const css::uno::Any& rValue, SfxItemSet& rSet); + } // namespace SwUnoCursorHelper #endif diff --git a/sw/qa/core/unocore/data/format-char-style-change.docx b/sw/qa/core/unocore/data/format-char-style-change.docx new file mode 100644 index 000000000000..febf5dc3231d Binary files /dev/null and b/sw/qa/core/unocore/data/format-char-style-change.docx differ diff --git a/sw/qa/core/unocore/unocrsrhelper.cxx b/sw/qa/core/unocore/unocrsrhelper.cxx new file mode 100644 index 000000000000..24bc03413a56 --- /dev/null +++ b/sw/qa/core/unocore/unocrsrhelper.cxx @@ -0,0 +1,65 @@ +/* -*- 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 + +#include +#include +#include +#include +#include + +using namespace com::sun::star; + +namespace +{ +/// Covers sw/source/core/unocore/unocrsrhelper.cxx fixes. +class Test : public SwModelTestBase +{ +public: + Test() + : SwModelTestBase(u"/sw/qa/core/unocore/data/"_ustr) + { + } +}; + +CPPUNIT_TEST_FIXTURE(Test, testFormatCharStyleChangeDocxImport) +{ + // Given a document with a format redline, containing a char style change (strong -> quote): + // When importing that document: + createSwDoc("format-char-style-change.docx"); + + // Then make sure the model has the new style name, the redline has the old style name: + SwDocShell* pDocShell = getSwDocShell(); + SwDoc* pDoc = pDocShell->GetDoc(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + pWrtShell->SttEndDoc(/*bStt=*/false); + SfxItemSetFixed aSet(pDoc->GetAttrPool()); + pWrtShell->GetCurAttr(aSet); + const SwFormatCharFormat& rNewCharFormat = aSet.Get(RES_TXTATR_CHARFMT); + CPPUNIT_ASSERT_EQUAL(u"Quote Char"_ustr, rNewCharFormat.GetCharFormat()->GetName().toString()); + const IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess(); + const SwRedlineTable& rRedlineTable = rIDRA.GetRedlineTable(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 0 + // i.e. the import result had no redlines. + CPPUNIT_ASSERT_EQUAL(static_cast(1), rRedlineTable.size()); + const SwRangeRedline* pRedline = rRedlineTable[0]; + auto pExtraData = dynamic_cast(pRedline->GetExtraData()); + CPPUNIT_ASSERT(pExtraData); + std::shared_ptr pRedlineSet = pExtraData->GetItemSet(); + CPPUNIT_ASSERT(pRedlineSet); + const SwFormatCharFormat& rOldCharFormat = pRedlineSet->Get(RES_TXTATR_CHARFMT); + CPPUNIT_ASSERT_EQUAL(u"Strong Emphasis"_ustr, + rOldCharFormat.GetCharFormat()->GetName().toString()); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx index defa0496db1a..f78a2c86f590 100644 --- a/sw/source/core/unocore/unocrsrhelper.cxx +++ b/sw/source/core/unocore/unocrsrhelper.cxx @@ -1324,6 +1324,7 @@ void makeRedline( SwPaM const & rPaM, std::vector aValues; aEntries.reserve(aRevertProperties.getLength()); sal_uInt16 nStyleId = USHRT_MAX; + sal_uInt16 nCharStyleId = USHRT_MAX; sal_uInt16 nNumId = USHRT_MAX; for (const auto& rRevertProperty : aRevertProperties) { @@ -1349,6 +1350,10 @@ void makeRedline( SwPaM const & rPaM, aWhichPairs = aWhichPairs.MergeRange(pEntry->nWID, pEntry->nWID); if (rPropertyName == "ParaStyleName") nStyleId = aEntries.size(); + else if (rPropertyName == "CharStyleName") + { + nCharStyleId = aEntries.size(); + } } aEntries.push_back(pEntry); aValues.push_back(rRevertProperty.Value); @@ -1378,6 +1383,11 @@ void makeRedline( SwPaM const & rPaM, pRule->SetUsedByRedline(true); } } + else if (i == nCharStyleId) + { + // Set this manually, SwFormatCharFormat::PutValue() would fail. + SwUnoCursorHelper::SetCharStyle(rDoc, rValue, aItemSet); + } else { SfxItemPropertyMapEntry const*const pEntry = aEntries[i]; diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx index 1c3f9d06a610..6921b3bba5ad 100644 --- a/sw/source/core/unocore/unoobj.cxx +++ b/sw/source/core/unocore/unoobj.cxx @@ -177,10 +177,12 @@ void SwUnoCursorHelper::GetTextFromPam(SwPaM & rPam, OUString & rBuffer, } +namespace SwUnoCursorHelper +{ /// @throws lang::IllegalArgumentException /// @throws uno::RuntimeException -static void -lcl_setCharStyle(SwDoc& rDoc, const uno::Any & rValue, SfxItemSet & rSet) +void +SetCharStyle(SwDoc& rDoc, const uno::Any & rValue, SfxItemSet & rSet) { SwDocShell *const pDocSh = rDoc.GetDocShell(); if(!pDocSh) @@ -203,6 +205,7 @@ lcl_setCharStyle(SwDoc& rDoc, const uno::Any & rValue, SfxItemSet & rSet) const SwFormatCharFormat aFormat(pStyle->GetCharFormat()); rSet.Put(aFormat); }; +} /// @throws lang::IllegalArgumentException static void @@ -352,7 +355,7 @@ lcl_setCharFormatSequence(SwPaM & rPam, uno::Any const& rValue) aStyle <<= aCharStyles.getConstArray()[nStyle]; // create a local set and apply each format directly SfxItemSetFixed aSet(rPam.GetDoc().GetAttrPool()); - lcl_setCharStyle(rPam.GetDoc(), aStyle, aSet); + SwUnoCursorHelper::SetCharStyle(rPam.GetDoc(), aStyle, aSet); // the first style should replace the current attributes, // all other have to be added SwUnoCursorHelper::SetCursorAttr(rPam, aSet, nStyle @@ -444,7 +447,7 @@ SwUnoCursorHelper::SetCursorPropertyValue( switch (rEntry.nWID) { case RES_TXTATR_CHARFMT: - lcl_setCharStyle(rPam.GetDoc(), rValue, rItemSet); + SwUnoCursorHelper::SetCharStyle(rPam.GetDoc(), rValue, rItemSet); break; case RES_TXTATR_AUTOFMT: lcl_setAutoStyle(rPam.GetDoc().GetIStyleAccess(), @@ -538,7 +541,7 @@ SwUnoCursorHelper::SetCursorPropertyValue( } if (prop.Name == "CharStyleName") { - lcl_setCharStyle(rPam.GetDoc(), prop.Value, items); + SwUnoCursorHelper::SetCharStyle(rPam.GetDoc(), prop.Value, items); } else {