sw/qa/filter/xml/data/format-charstyle-direct.odt |binary sw/qa/filter/xml/xml.cxx | 39 ++++++++++++++++++++++ sw/source/filter/xml/XMLRedlineImportHelper.cxx | 20 ++++++++--- 3 files changed, 54 insertions(+), 5 deletions(-)
New commits: commit bd6fea8f544ffd5fba18443c062d756f20fedd94 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Sep 3 08:53:47 2025 +0200 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Wed Sep 3 09:29:28 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/+/190550 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> 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 c260326d7cfd..f31d83be5a0d 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> @@ -154,6 +156,43 @@ CPPUNIT_TEST_FIXTURE(Test, testFormatCharStyleChangeOdtImport) const SwFormatCharFormat& rOldCharFormat = pRedlineSet->Get(RES_TXTATR_CHARFMT); CPPUNIT_ASSERT_EQUAL(u"Strong Emphasis"_ustr, rOldCharFormat.GetCharFormat()->GetName()); } + +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()); + 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()); + 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 eaf38350100e..211b88260a85 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) {