xmloff/qa/unit/data/nested-spans.odt |binary xmloff/qa/unit/text.cxx | 26 ++++++++++++++++++++++++++ xmloff/source/text/txtparai.cxx | 24 ++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 2 deletions(-)
New commits: commit 2d0f43befdaa1010062b534dffa82adad8c956c8 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Aug 14 08:10:51 2023 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Aug 14 09:17:55 2023 +0200 tdf#156321 ODT import: fix lost char format on outer span elements Regression from commit 209dce614c43f63f63f5b42a746665c0ec1cbfe3 (sw: fix ODT import of paragraph marker formatting, 2022-12-20), the bugdoc has a first paragraph with nested spans (the outer sets the boldness) and the text does not appear as bold in Writer anymore. What appears to be the problem is that our model is just a list of spans for a paragraph, so nesting is converted to a list of spans, but now the outer span char format is lost. Fix the problem by making the condition of the 'no upgrade from char format to para format' more strict: do this in case we have empty spans. That fixes this new use-case and leaves the original one fixed. Note that in the long run it may make sense to always disable the upgrade from char format to para format, but that has to be done in a way that does not break the import of nested spans. Change-Id: Ie6fafb3e9649e50790c7ecae8e136e6600f3341e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155648 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/xmloff/qa/unit/data/nested-spans.odt b/xmloff/qa/unit/data/nested-spans.odt new file mode 100644 index 000000000000..3e7b1dc9eb55 Binary files /dev/null and b/xmloff/qa/unit/data/nested-spans.odt differ diff --git a/xmloff/qa/unit/text.cxx b/xmloff/qa/unit/text.cxx index abd4a0e07dea..8c500dccce24 100644 --- a/xmloff/qa/unit/text.cxx +++ b/xmloff/qa/unit/text.cxx @@ -9,6 +9,7 @@ #include <test/unoapixml_test.hxx> +#include <com/sun/star/awt/FontWeight.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/PropertyValues.hpp> #include <com/sun/star/frame/XStorable.hpp> @@ -1249,6 +1250,31 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testParagraphScopedTabDistance) assertXPath(pXmlDoc, "//text:p[@text:style-name='P1']"); } +CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testNestedSpans) +{ + // Given a document with a first paragraph that has a nested span, the outer span setting the + // boldness: + // When importing that document: + loadFromURL(u"nested-spans.odt"); + + // Then make sure the text portion is bold, not normal: + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xTextDocument->getText(), + uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParagraphs = xParagraphsAccess->createEnumeration(); + uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(), + uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration(); + uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY); + float fWeight{}; + xTextPortion->getPropertyValue("CharWeight") >>= fWeight; + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 150 (awt::FontWeight::BOLD) + // - Actual : 100 (awt::FontWeight::NORMAL) + // i.e. the boldness was lost on import. + CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, fWeight); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/text/txtparai.cxx b/xmloff/source/text/txtparai.cxx index 5dc1b882b1b2..c777fa0c2929 100644 --- a/xmloff/source/text/txtparai.cxx +++ b/xmloff/source/text/txtparai.cxx @@ -34,6 +34,7 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XPropertySetInfo.hpp> #include <com/sun/star/text/ControlCharacter.hpp> +#include <com/sun/star/text/XTextRangeCompare.hpp> #include <com/sun/star/container/XIndexReplace.hpp> #include <com/sun/star/drawing/XShapes.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> @@ -1852,9 +1853,28 @@ void XMLParaContext::endFastElement(sal_Int32 ) { bool bSetNoFormatAttr = false; uno::Reference<beans::XPropertySet> xCursorProps(xAttrCursor, uno::UNO_QUERY); - if (m_xHints->GetHints().size() > 1 || m_aMarkerStyleName.hasValue()) + int nEmptyHints = 0; + uno::Reference<text::XTextRangeCompare> xCompare(xTxtImport->GetText(), uno::UNO_QUERY); + if (xCompare.is()) { - // We have multiple hints, then make try to ask the cursor to not upgrade our character + try + { + for (const auto& pHint : m_xHints->GetHints()) + { + if (xCompare->compareRegionStarts(pHint->GetStart(), pHint->GetEnd()) == 0) + { + ++nEmptyHints; + } + } + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("xmloff.text", ""); + } + } + if (nEmptyHints > 0 || m_aMarkerStyleName.hasValue()) + { + // We have at least one empty hint, then make try to ask the cursor to not upgrade our character // attributes to paragraph-level formatting, which would lead to incorrect rendering. uno::Reference<beans::XPropertySetInfo> xCursorPropsInfo = xCursorProps->getPropertySetInfo(); bSetNoFormatAttr = xCursorPropsInfo->hasPropertyByName("NoFormatAttr");