sw/qa/core/doc/DocumentRedlineManager.cxx | 44 ++++++++++++++++ sw/source/core/doc/DocumentContentOperationsManager.cxx | 7 ++ 2 files changed, 50 insertions(+), 1 deletion(-)
New commits: commit 1f6b2a4d6db61f0ae0f00774b3104cf679c3db4d Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Sep 18 08:50:41 2025 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Thu Sep 18 22:59:38 2025 +0200 tdf#168325 sw format redline, char style: improve recording Create a new Writer document with a single word in it, set the Emphasis character style on it, enable redline record, change char style to Strong Emphasis, save to ODT. The format redline refers to an automatic style, while it should refer to the old char style (Emphasis). This happens because the redline record for format redline works incorrectly: it not only records the char style (before changing the char style), but also the expanded value of the char style, which leads to the creation of an automatic style on ODT export. This doesn't happen if exporting an originally DOCX file to ODT. Fix the problem by explicitly asking for the current character properties in a way so that char styles are not expanded, when making a copy of the old formatting & storing it in a format redline. Also drop storing RSIDs in format redlines, they are not interesting and again would lead to unwanted creation of automatic styles. Change-Id: Idd34afb1f0570589254a9eb259af4fc3465aec22 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191120 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> (cherry picked from commit 0c7eaa023a840a6f0967fe119463a936241a8130) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191138 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/qa/core/doc/DocumentRedlineManager.cxx b/sw/qa/core/doc/DocumentRedlineManager.cxx index 8fac406a45aa..10221f79664a 100644 --- a/sw/qa/core/doc/DocumentRedlineManager.cxx +++ b/sw/qa/core/doc/DocumentRedlineManager.cxx @@ -11,6 +11,7 @@ #include <editeng/wghtitem.hxx> #include <comphelper/scopeguard.hxx> +#include <comphelper/propertyvalue.hxx> #include <IDocumentRedlineAccess.hxx> #include <docsh.hxx> @@ -19,6 +20,7 @@ #include <wrtsh.hxx> #include <swmodule.hxx> #include <strings.hrc> +#include <fchrfmt.hxx> namespace { @@ -128,6 +130,48 @@ CPPUNIT_TEST_FIXTURE(Test, testInsThenFormatSelf) // i.e. a delete was created instead of removing the insert. CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rRedlines.size()); } + +CPPUNIT_TEST_FIXTURE(Test, testFormatRedlineRecordOldCharStyle) +{ + // Given a document with one char style applied + redline record on: + createSwDoc(); + SwDocShell* pDocShell = getSwDocShell(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + pWrtShell->Insert(u"x"_ustr); + pWrtShell->SelAll(); + uno::Sequence<beans::PropertyValue> aPropertyValues = { + comphelper::makePropertyValue(u"Style"_ustr, uno::Any(u"Emphasis"_ustr)), + comphelper::makePropertyValue(u"FamilyName"_ustr, uno::Any(u"CharacterStyles"_ustr)), + }; + dispatchCommand(mxComponent, u".uno:StyleApply"_ustr, aPropertyValues); + pDocShell->SetChangeRecording(true); + + // When changing to a second char style: + aPropertyValues = { + comphelper::makePropertyValue(u"Style"_ustr, uno::Any(u"Strong Emphasis"_ustr)), + comphelper::makePropertyValue(u"FamilyName"_ustr, uno::Any(u"CharacterStyles"_ustr)), + }; + dispatchCommand(mxComponent, u".uno:StyleApply"_ustr, aPropertyValues); + + // Then make sure the redline refers to the old char style and just to that: + SwDoc* pDoc = pDocShell->GetDoc(); + IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess(); + SwRedlineTable& rRedlines = rIDRA.GetRedlineTable(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rRedlines.size()); + const SwRangeRedline& rRedline = *rRedlines[0]; + CPPUNIT_ASSERT_EQUAL(RedlineType::Format, rRedline.GetType()); + auto pExtraData = dynamic_cast<const SwRedlineExtraData_FormatColl*>(rRedline.GetExtraData()); + CPPUNIT_ASSERT(pExtraData); + std::shared_ptr<SfxItemSet> pRedlineSet = pExtraData->GetItemSet(); + CPPUNIT_ASSERT(pRedlineSet); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 5 + // i.e. more than just the char style change was recorded, which was unexpected. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), pRedlineSet->Count()); + const SwFormatCharFormat& rOldCharFormat = pRedlineSet->Get(RES_TXTATR_CHARFMT); + CPPUNIT_ASSERT_EQUAL(u"Emphasis"_ustr, rOldCharFormat.GetCharFormat()->GetName().toString()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 912ea1eb33cd..dd23ba2ed429 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -1303,7 +1303,11 @@ namespace //local functions originally from docfmt.cxx SfxItemSet aSet(SfxItemSet::makeFixedSfxItemSet<RES_CHRATR_BEGIN, RES_TXTATR_WITHEND_END - 1, RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1>(rDoc.GetAttrPool())); SwTextNode * pNode = rRg.Start()->GetNode().GetTextNode(); - pNode->GetParaAttr( aSet, rRg.Start()->GetContentIndex() + 1, rRg.End()->GetContentIndex() ); + // bGetFromChrFormat would be true by default and we want no expansion of the character + // style to direct formatting for redline purposes. + pNode->GetParaAttr(aSet, rRg.Start()->GetContentIndex() + 1, + rRg.End()->GetContentIndex(), /*bOnlyTextAttr=*/false, + /*bGetFromChrFormat=*/false); aSet.ClearItem( RES_TXTATR_REFMARK ); aSet.ClearItem( RES_TXTATR_TOXMARK ); @@ -1311,6 +1315,7 @@ namespace //local functions originally from docfmt.cxx aSet.ClearItem( RES_TXTATR_INETFMT ); aSet.ClearItem( RES_TXTATR_META ); aSet.ClearItem( RES_TXTATR_METAFIELD ); + aSet.ClearItem(RES_CHRATR_RSID); // After GetParaAttr aSet can contain invalid/dontcare items (true == IsInvalidItem, // DONTCARE == SfxItemState), e.g. RES_TXTATR_CHARFMT and (a copy of) this