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");

Reply via email to