sw/qa/filter/xml/data/format-charstyle-direct.odt |binary sw/qa/filter/xml/xml.cxx | 40 ++++++++++++++++++++++ sw/source/filter/xml/XMLRedlineImportHelper.cxx | 20 ++++++++--- 3 files changed, 55 insertions(+), 5 deletions(-)
New commits: commit e1e36df4fc2e7b8aaca82bbb00cfb9a414b0385a Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Sep 3 08:53:47 2025 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Wed Sep 10 11:10:06 2025 +0200 tdf#167761 sw format redline, char style+direct: add ODT import Open the bugdoc, it contains a format redline that changes the character style from Strong to Quote and the font size from 24 to 36. Revert the redline, the char style goes back to Strong, but the font size is 12, not 24. The problem is that only the char style was imported in XMLRedlineImportHelper::InsertIntoDocument(), because direct formatting is only handled when we have no char style. Fix the problem by creating an empty item set earlier, similar to how lcl_SetRedline() does it in the UI code, then both the char style and direct format can go into that item set. The format redline's ODT/DOCX filter is now in a reasonable shape with this. Change-Id: I28e2a43e218a319045649612e7492821e72649b5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190551 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> (cherry picked from commit bbebb3908ff9a9c384a475737ead537906517387) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190556 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/qa/filter/xml/data/format-charstyle-direct.odt b/sw/qa/filter/xml/data/format-charstyle-direct.odt new file mode 100644 index 000000000000..40b6df9528f0 Binary files /dev/null and b/sw/qa/filter/xml/data/format-charstyle-direct.odt differ diff --git a/sw/qa/filter/xml/xml.cxx b/sw/qa/filter/xml/xml.cxx index de92d086f482..6ab6f7595720 100644 --- a/sw/qa/filter/xml/xml.cxx +++ b/sw/qa/filter/xml/xml.cxx @@ -9,6 +9,8 @@ #include <swmodeltestbase.hxx> +#include <editeng/fhgtitem.hxx> + #include <frameformats.hxx> #include <frmatr.hxx> #include <swtable.hxx> @@ -155,6 +157,44 @@ CPPUNIT_TEST_FIXTURE(Test, testFormatCharStyleChangeOdtImport) CPPUNIT_ASSERT_EQUAL(u"Strong Emphasis"_ustr, rOldCharFormat.GetCharFormat()->GetName().toString()); } + +CPPUNIT_TEST_FIXTURE(Test, testFormatCharstyleDirectOdtImport) +{ + // Given a document with a format redline, containing a char style change (strong -> quote) and + // a font size change (24 -> 36pt): + // When importing that document: + createSwDoc("format-charstyle-direct.odt"); + + // Then make sure the model has the new style name & new font size, the redline has the old + // style name & old font size: + SwDocShell* pDocShell = getSwDocShell(); + SwDoc* pDoc = pDocShell->GetDoc(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + pWrtShell->SttEndDoc(/*bStt=*/false); + SfxItemSetFixed<RES_CHRATR_FONTSIZE, 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 SvxFontHeightItem& rNewFontSize = aSet.Get(RES_CHRATR_FONTSIZE); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(36 * 20), rNewFontSize.GetHeight()); + const IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess(); + const SwRedlineTable& rRedlineTable = rIDRA.GetRedlineTable(); + 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()); + const SvxFontHeightItem& rOldFontSize = pRedlineSet->Get(RES_CHRATR_FONTSIZE); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 480 + // - Actual : 240 + // i.e. the redline didn't contain a correct old font size (direct format). + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(24 * 20), rOldFontSize.GetHeight()); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/xml/XMLRedlineImportHelper.cxx b/sw/source/filter/xml/XMLRedlineImportHelper.cxx index eed1fd273e91..bf6ec7a1e2ca 100644 --- a/sw/source/filter/xml/XMLRedlineImportHelper.cxx +++ b/sw/source/filter/xml/XMLRedlineImportHelper.cxx @@ -798,22 +798,32 @@ void XMLRedlineImportHelper::InsertIntoDocument(RedlineInfo* pRedlineInfo) } // Create the redline's extra data if we have a matching autostyle. - std::shared_ptr<SfxItemSet> pAutoStyle; IStyleAccess& rStyleAccess = pDoc->GetIStyleAccess(); + SfxItemSetFixed<RES_CHRATR_BEGIN, RES_TXTATR_WITHEND_END - 1, RES_UNKNOWNATR_BEGIN, + RES_UNKNOWNATR_END - 1> + aItemSet(pDoc->GetAttrPool()); if (!pRedlineInfo->m_aStyleName.isEmpty()) { // Named character style. - SfxItemSetFixed<RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT> aItemSet(pDoc->GetAttrPool()); uno::Any aStyleName; aStyleName <<= pRedlineInfo->m_aStyleName; SwUnoCursorHelper::SetCharStyle(*pDoc, aStyleName, aItemSet); - pAutoStyle = rStyleAccess.getAutomaticStyle(aItemSet, IStyleAccess::AUTO_STYLE_CHAR); } - else if (!pRedlineInfo->m_aAutoName.isEmpty()) + if (!pRedlineInfo->m_aAutoName.isEmpty()) { // Just a set of character properties with an automatic name. - pAutoStyle + std::shared_ptr<SfxItemSet> pAutoStyle = rStyleAccess.getByName(pRedlineInfo->m_aAutoName, IStyleAccess::AUTO_STYLE_CHAR); + if (pAutoStyle) + { + aItemSet.Put(*pAutoStyle); + } + } + std::shared_ptr<SfxItemSet> pAutoStyle; + if (aItemSet.Count() > 0) + { + // Have a named style or direct format, create an automatic style. + pAutoStyle = rStyleAccess.getAutomaticStyle(aItemSet, IStyleAccess::AUTO_STYLE_CHAR); } if (pAutoStyle) {