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
{