include/xmloff/txtimp.hxx | 3 - sw/qa/filter/xml/data/format-char-style-change.odt |binary sw/qa/filter/xml/xml.cxx | 32 ++++++++++++++ sw/source/filter/xml/XMLRedlineImportHelper.cxx | 43 ++++++++++++------- sw/source/filter/xml/XMLRedlineImportHelper.hxx | 3 - sw/source/filter/xml/xmltexti.cxx | 5 +- sw/source/filter/xml/xmltexti.hxx | 3 - xmloff/source/text/XMLChangedRegionImportContext.cxx | 10 ++-- xmloff/source/text/XMLChangedRegionImportContext.hxx | 2 xmloff/source/text/txtimp.cxx | 3 - 10 files changed, 79 insertions(+), 25 deletions(-)
New commits: commit 5d30325108f80fbb6ac913b42e74a64a7e13bd72 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Aug 21 08:42:03 2025 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Thu Aug 21 19:26:06 2025 +0200 tdf#167761 sw format redline, char style: implement ODF import Load the bugdoc, the format redline at the doc end has the Quote char style, reverting the redline should result in the Strong char style, but results in no character style. What happens is that XMLChangedRegionImportContext::SetChangeInfo() assumed that the style name of the format redline is always an automatic style, while it may be a named character style, too. Fix the problem by splitting the style name into two parts in XMLChangedRegionImportContext::SetChangeInfo() (named style, automatic style) and then work with that pair in XMLRedlineImportHelper::InsertIntoDocument(), similar to how XMLTextImportHelper::SetStyleAndAttrs() works for <text:span>'s style name. The ODF export worked already. Change-Id: I2fa1479a0d2463556e84be566967325584bc14f7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189984 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins (cherry picked from commit 0ba6dd9eb3f342345663b12527a29425675d2078) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189995 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/include/xmloff/txtimp.hxx b/include/xmloff/txtimp.hxx index cb9b44145049..4d290f25327e 100644 --- a/include/xmloff/txtimp.hxx +++ b/include/xmloff/txtimp.hxx @@ -383,7 +383,8 @@ public: const OUString& rMoveId, /// merge last paras bool bMergeLastParagraph, - const OUString& rAutoStyleName); + const OUString& rStyleName, + const OUString& rAutoName); virtual css::uno::Reference< css::text::XTextCursor> RedlineCreateText( /// needed to get the document diff --git a/sw/qa/filter/xml/data/format-char-style-change.odt b/sw/qa/filter/xml/data/format-char-style-change.odt new file mode 100644 index 000000000000..03cddb9eea61 Binary files /dev/null and b/sw/qa/filter/xml/data/format-char-style-change.odt differ diff --git a/sw/qa/filter/xml/xml.cxx b/sw/qa/filter/xml/xml.cxx index de6d19aafd47..de92d086f482 100644 --- a/sw/qa/filter/xml/xml.cxx +++ b/sw/qa/filter/xml/xml.cxx @@ -15,6 +15,8 @@ #include <docsh.hxx> #include <IDocumentRedlineAccess.hxx> #include <redline.hxx> +#include <wrtsh.hxx> +#include <fchrfmt.hxx> namespace { @@ -123,6 +125,36 @@ CPPUNIT_TEST_FIXTURE(Test, testDeleteThenFormatOdtImport) CPPUNIT_ASSERT_EQUAL(RedlineType::Delete, rInnerRedlineData.GetType()); CPPUNIT_ASSERT_EQUAL(RedlineType::Delete, rRedlines[2]->GetType()); } + +CPPUNIT_TEST_FIXTURE(Test, testFormatCharStyleChangeOdtImport) +{ + // Given a document with a format redline, containing a char style change (strong -> quote): + // When importing that document: + createSwDoc("format-char-style-change.odt"); + + // 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(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rRedlineTable.size()); + const SwRangeRedline* pRedline = rRedlineTable[0]; + auto pExtraData = dynamic_cast<const SwRedlineExtraData_FormatColl*>(pRedline->GetExtraData()); + // Without the accompanying fix in place, this test would have failed, the format redline didn't + // contain the old style name. + 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()); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/xml/XMLRedlineImportHelper.cxx b/sw/source/filter/xml/XMLRedlineImportHelper.cxx index faece01160a8..eed1fd273e91 100644 --- a/sw/source/filter/xml/XMLRedlineImportHelper.cxx +++ b/sw/source/filter/xml/XMLRedlineImportHelper.cxx @@ -44,6 +44,7 @@ #include <xmloff/xmltoken.hxx> #include <vcl/svapp.hxx> #include <istyleaccess.hxx> +#include <unocrsrhelper.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -191,7 +192,8 @@ public: util::DateTime aDateTime; // change DateTime OUString sMovedID; // change move id string bool bMergeLastParagraph; // the SwRangeRedline::IsDelLastPara flag - OUString m_aAutoStyleName; + OUString m_aStyleName; + OUString m_aAutoName; // each position can may be either empty, an XTextRange, or an SwNodeIndex @@ -374,7 +376,8 @@ void XMLRedlineImportHelper::Add( const util::DateTime& rDateTime, const OUString& rMovedID, bool bMergeLastPara, - const OUString& rAutoStyleName) + const OUString& rStyleName, + const OUString& rAutoName) { // we need to do the following: // 1) parse type string @@ -413,7 +416,8 @@ void XMLRedlineImportHelper::Add( pInfo->aDateTime = rDateTime; pInfo->sMovedID = rMovedID; pInfo->bMergeLastParagraph = bMergeLastPara; - pInfo->m_aAutoStyleName = rAutoStyleName; + pInfo->m_aStyleName = rStyleName; + pInfo->m_aAutoName = rAutoName; //reserve MoveID so it won't be reused by others if (!rMovedID.isEmpty()) @@ -794,18 +798,29 @@ void XMLRedlineImportHelper::InsertIntoDocument(RedlineInfo* pRedlineInfo) } // Create the redline's extra data if we have a matching autostyle. - if (!pRedlineInfo->m_aAutoStyleName.isEmpty()) + std::shared_ptr<SfxItemSet> pAutoStyle; + IStyleAccess& rStyleAccess = pDoc->GetIStyleAccess(); + if (!pRedlineInfo->m_aStyleName.isEmpty()) { - IStyleAccess& rStyleAccess = pDoc->GetIStyleAccess(); - std::shared_ptr<SfxItemSet> pAutoStyle = rStyleAccess.getByName( - pRedlineInfo->m_aAutoStyleName, IStyleAccess::AUTO_STYLE_CHAR); - if (pAutoStyle) - { - sal_uInt16 nPoolFormatId = USHRT_MAX; - SwRedlineExtraData_FormatColl aExtraData(UIName(u""_ustr), nPoolFormatId, pAutoStyle); - // aExtraData is copied here. - pRedline->SetExtraData(&aExtraData); - } + // 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()) + { + // Just a set of character properties with an automatic name. + pAutoStyle + = rStyleAccess.getByName(pRedlineInfo->m_aAutoName, IStyleAccess::AUTO_STYLE_CHAR); + } + if (pAutoStyle) + { + sal_uInt16 nPoolFormatId = USHRT_MAX; + SwRedlineExtraData_FormatColl aExtraData(UIName(u""_ustr), nPoolFormatId, pAutoStyle); + // aExtraData is copied here. + pRedline->SetExtraData(&aExtraData); } // set redline mode (without doing the associated book-keeping) diff --git a/sw/source/filter/xml/XMLRedlineImportHelper.hxx b/sw/source/filter/xml/XMLRedlineImportHelper.hxx index 17228eaed57b..c89e76a89fb2 100644 --- a/sw/source/filter/xml/XMLRedlineImportHelper.hxx +++ b/sw/source/filter/xml/XMLRedlineImportHelper.hxx @@ -82,7 +82,8 @@ public: const css::util::DateTime& rDateTime, // date+time const OUString& rMovedID, // redline move id bool bMergeLastParagraph, // merge last paragraph? - const OUString& rAutoStyleName); + const OUString& rStyleName, + const OUString& rAutoName); // create a text section for the redline, and return an // XText/XTextCursor that may be used to write into it. diff --git a/sw/source/filter/xml/xmltexti.cxx b/sw/source/filter/xml/xmltexti.cxx index 1baa124fb6df..d4acb5fd6940 100644 --- a/sw/source/filter/xml/xmltexti.cxx +++ b/sw/source/filter/xml/xmltexti.cxx @@ -926,13 +926,14 @@ void SwXMLTextImportHelper::RedlineAdd( const util::DateTime& rDateTime, const OUString& rMovedID, bool bMergeLastPara, - const OUString& rAutoStyleName) + const OUString& rStyleName, + const OUString& rAutoName) { // create redline helper on demand OSL_ENSURE(nullptr != m_pRedlineHelper, "helper should have been created in constructor"); if (nullptr != m_pRedlineHelper) m_pRedlineHelper->Add(rType, rId, rAuthor, rComment, rDateTime, rMovedID, - bMergeLastPara, rAutoStyleName); + bMergeLastPara, rStyleName, rAutoName); } uno::Reference<XTextCursor> SwXMLTextImportHelper::RedlineCreateText( diff --git a/sw/source/filter/xml/xmltexti.hxx b/sw/source/filter/xml/xmltexti.hxx index ccb06a53ac22..303b7131cf4a 100644 --- a/sw/source/filter/xml/xmltexti.hxx +++ b/sw/source/filter/xml/xmltexti.hxx @@ -92,7 +92,8 @@ public: const css::util::DateTime& rDateTime, /// date+time const OUString& rMovedID, /// redline move id, to find moveFrom/MoveTo parts bool bMergeLastPara, /// merge last paragraph - const OUString& rAutoStyleName) override; + const OUString& rStyleName, + const OUString& rAutoName) override; virtual css::uno::Reference<css::text::XTextCursor> RedlineCreateText( css::uno::Reference<css::text::XTextCursor> & rOldCursor, /// needed to get the document const OUString& rId) override; /// ID used to RedlineAdd() call diff --git a/xmloff/source/text/XMLChangedRegionImportContext.cxx b/xmloff/source/text/XMLChangedRegionImportContext.cxx index b29980528ff2..d3ee8e336168 100644 --- a/xmloff/source/text/XMLChangedRegionImportContext.cxx +++ b/xmloff/source/text/XMLChangedRegionImportContext.cxx @@ -103,7 +103,7 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > XMLChangedRegionImport switch (rAttribute.getToken()) { case XML_ELEMENT(LO_EXT, XML_STYLE_NAME): - m_aAutoStyleName = rAttribute.toString(); + m_aStyleName = rAttribute.toString(); break; default: XMLOFF_WARN_UNKNOWN("xmloff", rAttribute); @@ -157,15 +157,17 @@ void XMLChangedRegionImportContext::SetChangeInfo( { // If the format redline has an autostyle, look up the internal 'auto name'. OUString aAutoName; - if (!m_aAutoStyleName.isEmpty()) + if (!m_aStyleName.isEmpty()) { rtl::Reference<XMLTextImportHelper> xHelper = GetImport().GetTextImport(); // Map the XML-level automatic style name (e.g. T1) to an 'auto name' that exists in the // char auto style pool (e.g. 3cb7b270). - XMLPropStyleContext* pStyle = xHelper->FindAutoCharStyle(m_aAutoStyleName); + XMLPropStyleContext* pStyle = xHelper->FindAutoCharStyle(m_aStyleName); + // Split m_aStyleName into a named character style and an autostyle. if (pStyle) { pStyle->GetAutoName() >>= aAutoName; + m_aStyleName = pStyle->GetParentName(); } } @@ -173,7 +175,7 @@ void XMLChangedRegionImportContext::SetChangeInfo( if (::sax::Converter::parseDateTime(aDateTime, rDate)) { GetImport().GetTextImport()->RedlineAdd( - rType, sID, rAuthor, rComment, aDateTime, rMovedID, bMergeLastPara, aAutoName); + rType, sID, rAuthor, rComment, aDateTime, rMovedID, bMergeLastPara, m_aStyleName, aAutoName); } } diff --git a/xmloff/source/text/XMLChangedRegionImportContext.hxx b/xmloff/source/text/XMLChangedRegionImportContext.hxx index e12a9298597f..60362cbf3e1a 100644 --- a/xmloff/source/text/XMLChangedRegionImportContext.hxx +++ b/xmloff/source/text/XMLChangedRegionImportContext.hxx @@ -46,7 +46,7 @@ class XMLChangedRegionImportContext : public SvXMLImportContext /// merge-last-paragraph flag bool bMergeLastPara; - OUString m_aAutoStyleName; + OUString m_aStyleName; public: diff --git a/xmloff/source/text/txtimp.cxx b/xmloff/source/text/txtimp.cxx index 4415fde16a25..339872247fd5 100644 --- a/xmloff/source/text/txtimp.cxx +++ b/xmloff/source/text/txtimp.cxx @@ -2329,7 +2329,8 @@ void XMLTextImportHelper::RedlineAdd( const OUString& /*rType*/, const util::DateTime& /*rDateTime*/, const OUString& /*rMovedID*/, bool /*bMergeLastPara*/, - const OUString& /*rAutoStyleName*/) + const OUString& /*rStyleName*/, + const OUString& /*rAutoName*/) { // dummy implementation: do nothing }