tdf#167761 sw format redline, char style: implement DOCX import
Open the bugdoc, there should be a format redline that tracks the change of the char style from Strong to QuoteChar, but the doc model contains no redlines. What happens is that we try to handle character style as a character property, but SwUnoCursorHelper::makeRedline() uses SfxItemPropertySet::setPropertyValue() for CharStyleName, which calls into SwFormatCharFormat::PutValue(), which fails, so the redline is not created. Fix the problem by reusing lcl_setCharStyle(), that knows how to set the character style on an item set. The DOCX export worked already. Change-Id: I9479cadfdf6cb598cd4b11d49d851236c8ec09e3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189918 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
This commit is contained in:
@@ -4160,7 +4160,7 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<!-- https://lists.freedesktop.org/archives/libreoffice/2025-May/093327.html Hierarchical tracked changes -->
|
||||
<!-- https://issues.oasis-open.org/browse/OFFICE-4174 Hierarchical tracked changes -->
|
||||
<rng:define name="text-changed-region" combine="choice">
|
||||
<rng:element name="text:changed-region">
|
||||
<rng:ref name="text-changed-region-attr"/>
|
||||
@@ -4171,7 +4171,7 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<!-- TODO(vmiklos) no proposal for style on format changes -->
|
||||
<!-- https://issues.oasis-open.org/browse/OFFICE-4173 Style on format changes -->
|
||||
<rng:define name="text-changed-region-content" combine="choice">
|
||||
<rng:element name="text:format-change">
|
||||
<rng:optional>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -242,6 +242,8 @@ namespace SwUnoCursorHelper
|
||||
css::uno::Reference<css::text::XFlatParagraphIterator>
|
||||
CreateFlatParagraphIterator(SwDoc &, sal_Int32, bool);
|
||||
|
||||
void SetCharStyle(SwDoc& rDoc, const css::uno::Any& rValue, SfxItemSet& rSet);
|
||||
|
||||
} // namespace SwUnoCursorHelper
|
||||
|
||||
#endif
|
||||
|
||||
Binary file not shown.
@@ -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 <swmodeltestbase.hxx>
|
||||
|
||||
#include <IDocumentRedlineAccess.hxx>
|
||||
#include <docsh.hxx>
|
||||
#include <fchrfmt.hxx>
|
||||
#include <redline.hxx>
|
||||
#include <wrtsh.hxx>
|
||||
|
||||
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<RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT> 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<size_t>(1), rRedlineTable.size());
|
||||
const SwRangeRedline* pRedline = rRedlineTable[0];
|
||||
auto pExtraData = dynamic_cast<const SwRedlineExtraData_FormatColl*>(pRedline->GetExtraData());
|
||||
CPPUNIT_ASSERT(pExtraData);
|
||||
std::shared_ptr<SfxItemSet> 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: */
|
||||
@@ -1324,6 +1324,7 @@ void makeRedline( SwPaM const & rPaM,
|
||||
std::vector<uno::Any> 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];
|
||||
|
||||
@@ -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<RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT> 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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user