sw/qa/extras/odfexport/data/tdf114287.odt              |binary
 sw/qa/extras/odfexport/odfexport2.cxx                  |   45 +++++++++++++++++
 sw/qa/extras/ooxmlexport/data/image_through_shape.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport16.cxx             |    9 +++
 writerfilter/source/dmapper/DomainMapper.cxx           |   14 ++---
 writerfilter/source/dmapper/DomainMapper_Impl.cxx      |   22 ++++----
 writerfilter/source/dmapper/DomainMapper_Impl.hxx      |    5 +
 writerfilter/source/dmapper/GraphicImport.cxx          |   44 +++++++++-------
 writerfilter/source/dmapper/GraphicImport.hxx          |    2 
 xmloff/source/text/XMLTextListBlockContext.hxx         |    2 
 xmloff/source/text/txtimp.cxx                          |   11 +++-
 11 files changed, 112 insertions(+), 42 deletions(-)

New commits:
commit 043c349f144b615836091707147e57616a1261e7
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Tue Feb 28 14:40:08 2023 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Tue Feb 28 15:43:55 2023 +0000

    tdf#153874 writerfilter: fix anchoring of decorative shapes
    
    Turns out as-char flys can be decorative too.
    
    The confusing GraphicImport takes a GraphicImportType by value but
    everything else is a reference to a DomainMapper_Impl member.
    
    The latter appears to work better so handle GraphicImportType the same
    way and remove the function parameter.
    
    (regression from commit 31084ebb59093be7dfe5ab53a20fdb3bcfde34b6)
    
    Change-Id: I18c1d47d39751e8ddcaa52498077d89c43a934e9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147998
    Tested-by: Michael Stahl <michael.st...@allotropia.de>
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/qa/extras/ooxmlexport/data/image_through_shape.docx 
b/sw/qa/extras/ooxmlexport/data/image_through_shape.docx
new file mode 100644
index 000000000000..dd90f9d9bf29
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/image_through_shape.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index 99c0b2c9ffe7..9eb7eabd2434 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
@@ -823,6 +823,15 @@ DECLARE_OOXMLEXPORT_TEST(testTdf133473_shadowSize, 
"tdf133473.docx")
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(200000), nSize1);
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf153874, "image_through_shape.docx")
+{
+    uno::Reference<beans::XPropertySet> const 
xShape1(getShapeByName(u"Test1"),  uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> const 
xShape2(getShapeByName(u"Rectangle 1"), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER, 
xShape1->getPropertyValue("AnchorType").get<text::TextContentAnchorType>());
+    CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, 
xShape2->getPropertyValue("AnchorType").get<text::TextContentAnchorType>());
+    CPPUNIT_ASSERT_LESS(xShape2->getPropertyValue("ZOrder").get<sal_uInt64>(), 
xShape1->getPropertyValue("ZOrder").get<sal_uInt64>());
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTextBoxZOrder, "testTextBoxZOrder.docx")
 {
     // Is load successful?
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 242a0d655e39..573a1b41f4a5 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -776,8 +776,9 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
         {
             //looks a bit like a hack - and it is. The graphic import is split 
into the inline_inline part and
             //afterwards the adding of the binary data.
-            m_pImpl->GetGraphicImport( IMPORT_AS_DETECTED_INLINE 
)->attribute(nName, val);
-            m_pImpl->ImportGraphic( val.getProperties(), 
IMPORT_AS_DETECTED_INLINE );
+            m_pImpl->m_eGraphicImportType = IMPORT_AS_DETECTED_INLINE; // 
really ???
+            m_pImpl->GetGraphicImport()->attribute(nName, val);
+            m_pImpl->ImportGraphic(val.getProperties());
         }
         break;
         case NS_ooxml::LN_Value_math_ST_Jc_centerGroup:
@@ -1337,7 +1338,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
             }
             break;
         case NS_ooxml::LN_OfficeArtExtension_Decorative_val:
-            
m_pImpl->GetGraphicImport(IMPORT_AS_DETECTED_ANCHOR)->attribute(nName, val);
+            m_pImpl->GetGraphicImport()->attribute(nName, val);
             break;
         default:
             SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled 
token: " << nName);
@@ -2539,15 +2540,14 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
         writerfilter::Reference<Properties>::Pointer_t pProperties = 
rSprm.getProps();
         if( pProperties )
         {
-            GraphicImportType eGraphicType =
+            m_pImpl->m_eGraphicImportType =
                 (NS_ooxml::LN_anchor_anchor ==
                  sal::static_int_cast<Id>(nSprmId)) ?
                 IMPORT_AS_DETECTED_ANCHOR :
                 IMPORT_AS_DETECTED_INLINE;
-            GraphicImportPtr pGraphicImport =
-                m_pImpl->GetGraphicImport(eGraphicType);
+            GraphicImportPtr pGraphicImport = m_pImpl->GetGraphicImport();
             pProperties->resolve(*pGraphicImport);
-            m_pImpl->ImportGraphic(pProperties, eGraphicType);
+            m_pImpl->ImportGraphic(pProperties);
             if( !pGraphicImport->IsGraphic() )
             {
                 m_pImpl->ResetGraphicImport();
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 558d71f90fe7..bc5b44ac4863 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -8218,10 +8218,12 @@ void DomainMapper_Impl::AddAnnotationPosition(
     m_aAnnotationPositions[ nAnnotationId ] = aAnnotationPosition;
 }
 
-GraphicImportPtr const & DomainMapper_Impl::GetGraphicImport(GraphicImportType 
eGraphicImportType)
+GraphicImportPtr const & DomainMapper_Impl::GetGraphicImport()
 {
     if(!m_pGraphicImport)
-        m_pGraphicImport = new GraphicImport( m_xComponentContext, 
m_xTextFactory, m_rDMapper, eGraphicImportType, m_aPositionOffsets, m_aAligns, 
m_aPositivePercentages );
+    {
+        m_pGraphicImport = new GraphicImport(m_xComponentContext, 
m_xTextFactory, m_rDMapper, m_eGraphicImportType, m_aPositionOffsets, 
m_aAligns, m_aPositivePercentages);
+    }
     return m_pGraphicImport;
 }
 /*-------------------------------------------------------------------------
@@ -8233,11 +8235,11 @@ void DomainMapper_Impl::ResetGraphicImport()
 }
 
 
-void  DomainMapper_Impl::ImportGraphic(const writerfilter::Reference< 
Properties >::Pointer_t& ref, GraphicImportType eGraphicImportType)
+void  DomainMapper_Impl::ImportGraphic(const 
writerfilter::Reference<Properties>::Pointer_t& ref)
 {
-    GetGraphicImport(eGraphicImportType);
-    if( eGraphicImportType != IMPORT_AS_DETECTED_INLINE && eGraphicImportType 
!= IMPORT_AS_DETECTED_ANCHOR )
-    {
+    GetGraphicImport();
+    if (m_eGraphicImportType != IMPORT_AS_DETECTED_INLINE && 
m_eGraphicImportType != IMPORT_AS_DETECTED_ANCHOR)
+    {   // this appears impossible?
         //create the graphic
         ref->resolve( *m_pGraphicImport );
     }
@@ -8288,7 +8290,7 @@ void  DomainMapper_Impl::ImportGraphic(const 
writerfilter::Reference< Properties
 
         uno::Reference<drawing::XShape> xShape = 
m_pGraphicImport->GetXShapeObject();
         UpdateEmbeddedShapeProps(xShape);
-        if (eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
+        if (m_eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
         {
             uno::Reference<beans::XPropertySet> xEmbeddedProps(m_xEmbedded, 
uno::UNO_QUERY);
             xEmbeddedProps->setPropertyValue("AnchorType", 
uno::Any(text::TextContentAnchorType_AT_CHARACTER));
@@ -8313,7 +8315,7 @@ void  DomainMapper_Impl::ImportGraphic(const 
writerfilter::Reference< Properties
     {
         bool bAppend = true;
         // workaround for images anchored to characters: add ZWSPs around the 
anchoring point
-        if ( eGraphicImportType != IMPORT_AS_DETECTED_INLINE && 
!m_aRedlines.top().empty() )
+        if (m_eGraphicImportType != IMPORT_AS_DETECTED_INLINE && 
!m_aRedlines.top().empty())
         {
             uno::Reference< text::XTextAppend > xTextAppend = 
m_aTextAppendStack.top().xTextAppend;
             if(xTextAppend.is())
@@ -8342,7 +8344,7 @@ void  DomainMapper_Impl::ImportGraphic(const 
writerfilter::Reference< Properties
         if ( bAppend )
             appendTextContent( xTextContent, uno::Sequence< 
beans::PropertyValue >() );
 
-        if (eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR && 
!m_aTextAppendStack.empty())
+        if (m_eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR && 
!m_aTextAppendStack.empty())
         {
             // Remember this object is anchored to the current paragraph.
             AnchoredObjectInfo aInfo;
@@ -8355,7 +8357,7 @@ void  DomainMapper_Impl::ImportGraphic(const 
writerfilter::Reference< Properties
             }
             m_aTextAppendStack.top().m_aAnchoredObjects.push_back(aInfo);
         }
-        else if (eGraphicImportType == IMPORT_AS_DETECTED_INLINE)
+        else if (m_eGraphicImportType == IMPORT_AS_DETECTED_INLINE)
         {
             m_bParaWithInlineObject = true;
 
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 22e6e527d5c0..234ae9416eb1 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -827,10 +827,10 @@ public:
         return m_pSettingsTable;
     }
 
-    GraphicImportPtr const & GetGraphicImport( GraphicImportType 
eGraphicImportType );
+    GraphicImportPtr const & GetGraphicImport();
     void            ResetGraphicImport();
     // this method deletes the current m_pGraphicImport after import
-    void    ImportGraphic(const writerfilter::Reference< 
Properties>::Pointer_t&, GraphicImportType eGraphicImportType );
+    void    ImportGraphic(const 
writerfilter::Reference<Properties>::Pointer_t&);
 
     void InitTabStopFromStyle(const css::uno::Sequence<css::style::TabStop>& 
rInitTabStops);
     void    IncorporateTabStop( const DeletableTabStop &aTabStop );
@@ -1161,6 +1161,7 @@ public:
     std::pair<OUString, OUString> m_aAligns;
     /// ST_PositivePercentage values we received
     std::queue<OUString> m_aPositivePercentages;
+    enum GraphicImportType m_eGraphicImportType = {};
     bool isInIndexContext() const { return m_bStartIndex;}
     bool isInBibliographyContext() const { return m_bStartBibliography;}
     SmartTagHandler& getSmartTagHandler() { return m_aSmartTagHandler; }
diff --git a/writerfilter/source/dmapper/GraphicImport.cxx 
b/writerfilter/source/dmapper/GraphicImport.cxx
index f73c1e9de56f..c8c1e392f2c0 100644
--- a/writerfilter/source/dmapper/GraphicImport.cxx
+++ b/writerfilter/source/dmapper/GraphicImport.cxx
@@ -204,7 +204,7 @@ private:
     bool      m_bYSizeValid;
 
 public:
-    GraphicImportType m_eGraphicImportType;
+    GraphicImportType & m_rGraphicImportType;
     DomainMapper&   m_rDomainMapper;
 
     sal_Int32 m_nLeftPosition;
@@ -272,12 +272,15 @@ public:
     std::optional<sal_Int32> m_oEffectExtentRight;
     std::optional<sal_Int32> m_oEffectExtentBottom;
 
-    GraphicImport_Impl(GraphicImportType eImportType, DomainMapper& rDMapper, 
std::pair<OUString, OUString>& rPositionOffsets, std::pair<OUString, OUString>& 
rAligns, std::queue<OUString>& rPositivePercentages) :
-        m_nXSize(0)
+    GraphicImport_Impl(GraphicImportType & rImportType, DomainMapper& rDMapper,
+            std::pair<OUString, OUString>& rPositionOffsets,
+            std::pair<OUString, OUString>& rAligns,
+            std::queue<OUString>& rPositivePercentages)
+        : m_nXSize(0)
         ,m_bXSizeValid(false)
         ,m_nYSize(0)
         ,m_bYSizeValid(false)
-        ,m_eGraphicImportType( eImportType )
+        ,m_rGraphicImportType(rImportType)
         ,m_rDomainMapper( rDMapper )
         ,m_nLeftPosition(0)
         ,m_nTopPosition(0)
@@ -315,11 +318,6 @@ public:
         ,m_rAligns(rAligns)
         ,m_rPositivePercentages(rPositivePercentages)
     {
-        if (m_eGraphicImportType == 
GraphicImportType::IMPORT_AS_DETECTED_INLINE
-            && !rDMapper.IsInShape())
-        {
-            m_zOrder = 0;
-        }
     }
 
     void setXSize(sal_Int32 _nXSize)
@@ -388,14 +386,19 @@ public:
 
     void applyZOrder(uno::Reference<beans::XPropertySet> const & 
xGraphicObjectProperties) const
     {
-        if (m_zOrder >= 0)
+        sal_Int32 nZOrder = m_zOrder;
+        if (m_rGraphicImportType == 
GraphicImportType::IMPORT_AS_DETECTED_INLINE
+            && !m_rDomainMapper.IsInShape())
+        {
+            nZOrder = 0;
+        }
+        if (nZOrder >= 0)
         {
             // tdf#120760 Send objects with behinddoc=true to the back.
-            sal_Int32 nZOrder = m_zOrder;
             if (m_bBehindDoc && m_rDomainMapper.IsInHeaderFooter())
                 nZOrder -= SAL_MAX_INT32;
             GraphicZOrderHelper* pZOrderHelper = 
m_rDomainMapper.graphicZOrderHelper();
-            bool bOldStyle = m_eGraphicImportType == 
GraphicImportType::IMPORT_AS_DETECTED_INLINE;
+            bool const bOldStyle(m_rGraphicImportType == 
GraphicImportType::IMPORT_AS_DETECTED_INLINE);
             
xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_Z_ORDER),
                 uno::Any(pZOrderHelper->findZOrder(nZOrder, bOldStyle)));
             pZOrderHelper->addItem(xGraphicObjectProperties, nZOrder);
@@ -456,14 +459,14 @@ public:
 GraphicImport::GraphicImport(uno::Reference<uno::XComponentContext> 
xComponentContext,
                              uno::Reference<lang::XMultiServiceFactory> 
xTextFactory,
                              DomainMapper& rDMapper,
-                             GraphicImportType eImportType,
+                             GraphicImportType & rImportType,
                              std::pair<OUString, OUString>& rPositionOffsets,
                              std::pair<OUString, OUString>& rAligns,
                              std::queue<OUString>& rPositivePercentages)
 : LoggedProperties("GraphicImport")
 , LoggedTable("GraphicImport")
 , LoggedStream("GraphicImport")
-, m_pImpl(new GraphicImport_Impl(eImportType, rDMapper, rPositionOffsets, 
rAligns, rPositivePercentages))
+, m_pImpl(new GraphicImport_Impl(rImportType, rDMapper, rPositionOffsets, 
rAligns, rPositivePercentages))
 , m_xComponentContext(std::move(xComponentContext))
 , m_xTextFactory(std::move(xTextFactory))
 {
@@ -1015,7 +1018,7 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue)
                             lcl_correctWord2007EffectExtent(nOOXAngle);
                         }
 
-                        if (m_pImpl->m_eGraphicImportType == 
IMPORT_AS_DETECTED_INLINE)
+                        if (m_pImpl->m_rGraphicImportType == 
IMPORT_AS_DETECTED_INLINE)
                         {
                             if (nOOXAngle == 0)
                             {
@@ -1235,7 +1238,7 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue)
                             m_pImpl->m_nBottomMargin = 0;
                     }
 
-                    if (bUseShape && m_pImpl->m_eGraphicImportType == 
IMPORT_AS_DETECTED_ANCHOR)
+                    if (bUseShape && m_pImpl->m_rGraphicImportType == 
IMPORT_AS_DETECTED_ANCHOR)
                     {
                         // If we are here, this is a drawingML shape. For 
those, only dmapper (and not oox) knows the anchoring infos (just like for 
Writer pictures).
                         // But they aren't Writer pictures, either (which are 
already handled above).
@@ -1342,7 +1345,7 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue)
                         aInteropGrabBag.update(m_pImpl->getInteropGrabBag());
                         xShapeProps->setPropertyValue("InteropGrabBag", 
uno::Any(aInteropGrabBag.getAsConstPropertyValueList()));
                     }
-                    else if (bUseShape && m_pImpl->m_eGraphicImportType == 
IMPORT_AS_DETECTED_INLINE)
+                    else if (bUseShape && m_pImpl->m_rGraphicImportType == 
IMPORT_AS_DETECTED_INLINE)
                     {
                         uno::Reference< beans::XPropertySet > 
xShapeProps(m_xShape, uno::UNO_QUERY_THROW);
                         m_pImpl->applyMargins(xShapeProps);
@@ -1718,7 +1721,7 @@ uno::Reference<text::XTextContent> 
GraphicImport::createGraphicObject(uno::Refer
                 uno::UNO_QUERY_THROW);
             
xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_GRAPHIC), 
uno::Any(rxGraphic));
             
xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_ANCHOR_TYPE),
-                uno::Any( m_pImpl->m_eGraphicImportType == 
IMPORT_AS_DETECTED_ANCHOR ?
+                uno::Any( m_pImpl->m_rGraphicImportType == 
IMPORT_AS_DETECTED_ANCHOR ?
                                     text::TextContentAnchorType_AT_CHARACTER :
                                     text::TextContentAnchorType_AS_CHARACTER 
));
             xGraphicObject.set( xGraphicObjectProperties, uno::UNO_QUERY_THROW 
);
@@ -1793,7 +1796,7 @@ uno::Reference<text::XTextContent> 
GraphicImport::createGraphicObject(uno::Refer
                     uno::Any(true));
 
             sal_Int32 nWidth = - m_pImpl->m_nLeftPosition;
-            if (m_pImpl->m_eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
+            if (m_pImpl->m_rGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
             {
                 
xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_DECORATIVE), 
uno::Any(m_pImpl->m_bDecorative));
                 //adjust margins
@@ -1917,7 +1920,8 @@ uno::Reference<text::XTextContent> 
GraphicImport::createGraphicObject(uno::Refer
             }
 
 
-            if(m_pImpl->m_eGraphicImportType == IMPORT_AS_DETECTED_INLINE || 
m_pImpl->m_eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
+            if (m_pImpl->m_rGraphicImportType == IMPORT_AS_DETECTED_INLINE
+                || m_pImpl->m_rGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
             {
                 if( m_pImpl->getXSize() && m_pImpl->getYSize() )
                     
xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_SIZE),
diff --git a/writerfilter/source/dmapper/GraphicImport.hxx 
b/writerfilter/source/dmapper/GraphicImport.hxx
index 9bd3f4aaaa3e..9729aecace62 100644
--- a/writerfilter/source/dmapper/GraphicImport.hxx
+++ b/writerfilter/source/dmapper/GraphicImport.hxx
@@ -84,7 +84,7 @@ public:
     explicit GraphicImport( css::uno::Reference<css::uno::XComponentContext>  
xComponentContext,
                             
css::uno::Reference<css::lang::XMultiServiceFactory> xTextFactory,
                             DomainMapper& rDomainMapper,
-                            GraphicImportType eGraphicImportType,
+                            GraphicImportType & rGraphicImportType,
                             std::pair<OUString, OUString>& rPositionOffsets,
                             std::pair<OUString, OUString>& rAligns,
                             std::queue<OUString>& rPositivePercentages);
commit ade0a153f453500f15343380ac937252992733e0
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Mon Feb 27 20:52:39 2023 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Tue Feb 28 15:43:40 2023 +0000

    tdf#114287 xmloff: ODF import: fix text:list override of list style
    
    The problem is that the list element applies a list style, which should
    override the list style that's set in the common style
    "myStyleWithNumbering" of the paragraph, but these happend to be the
    same list styles and so the override was skipped, resulting in bad text
    formatting.
    
    <text:list xml:id="list3425910577850" text:continue-numbering="true" 
text:style-name="Numbering_20_123">
    
    The same problem exists if the list-item element has a style-override.
    
    This is similar to bug i#101349 which fixed it for an automatic
    paragraph style applying the same list style as its parent style.
    
    Change-Id: Idc6f10f93976de7e7bdceccbe3012c4157f61ad1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147930
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/qa/extras/odfexport/data/tdf114287.odt 
b/sw/qa/extras/odfexport/data/tdf114287.odt
new file mode 100644
index 000000000000..a9e9d38e29bf
Binary files /dev/null and b/sw/qa/extras/odfexport/data/tdf114287.odt differ
diff --git a/sw/qa/extras/odfexport/odfexport2.cxx 
b/sw/qa/extras/odfexport/odfexport2.cxx
index 3cae8e8987bd..e4da067f5396 100644
--- a/sw/qa/extras/odfexport/odfexport2.cxx
+++ b/sw/qa/extras/odfexport/odfexport2.cxx
@@ -818,6 +818,51 @@ CPPUNIT_TEST_FIXTURE(Test, tdf120972)
         "char", cDecimal);
 }
 
+DECLARE_ODFEXPORT_TEST(testTdf114287, "tdf114287.odt")
+{
+    uno::Reference<container::XIndexAccess> const xLevels1(
+        getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(2), 
"NumberingRules"));
+    uno::Reference<container::XNamed> const xNum1(xLevels1, uno::UNO_QUERY);
+    ::comphelper::SequenceAsHashMap props1(xLevels1->getByIndex(0));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(-700), 
props1["FirstLineIndent"].get<sal_Int32>());
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1330), props1["IndentAt"].get<sal_Int32>());
+
+    // 1: automatic style applies list-style-name and margin-left
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(-1000), 
getProperty<sal_Int32>(getParagraph(2), "ParaFirstLineIndent"));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(5001), 
getProperty<sal_Int32>(getParagraph(2), "ParaLeftMargin"));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraph(2), 
"ParaRightMargin"));
+
+    // list is continued
+    uno::Reference<container::XNamed> const xNum2(
+        getProperty<uno::Reference<container::XNamed>>(getParagraph(9), 
"NumberingRules"));
+    CPPUNIT_ASSERT_EQUAL(xNum1->getName(), xNum2->getName());
+
+    // 2: style applies list-style-name and margin-left, list applies 
list-style-name
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(-1000), 
getProperty<sal_Int32>(getParagraph(9), "ParaFirstLineIndent"));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(5001), 
getProperty<sal_Int32>(getParagraph(9), "ParaLeftMargin"));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraph(9), 
"ParaRightMargin"));
+
+    // list is continued
+    uno::Reference<container::XNamed> const xNum3(
+        getProperty<uno::Reference<container::XNamed>>(getParagraph(16), 
"NumberingRules"));
+    CPPUNIT_ASSERT_EQUAL(xNum1->getName(), xNum3->getName());
+
+    // 3: style applies margin-left, automatic style applies list-style-name
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(-1000), 
getProperty<sal_Int32>(getParagraph(16), "ParaFirstLineIndent"));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(5001), 
getProperty<sal_Int32>(getParagraph(16), "ParaLeftMargin"));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), 
getProperty<sal_Int32>(getParagraph(16), "ParaRightMargin"));
+
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/infos/prtBounds", "left", 
"2268");
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/infos/prtBounds", "right", 
"11339");
+    // the problem was that the list style name of the list must override the
+    // paragraph style even though it's the same list style
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[9]/infos/prtBounds", "left", 
"357");
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[9]/infos/prtBounds", "right", 
"11339");
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[16]/infos/prtBounds", "left", 
"357");
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[16]/infos/prtBounds", 
"right", "11339");
+}
+
 DECLARE_ODFEXPORT_TEST(testSectionColumnSeparator, 
"section-columns-separator.fodt")
 {
     // tdf#150235: due to wrong types used in column export, 'style:height' 
and 'style:style'
diff --git a/xmloff/source/text/XMLTextListBlockContext.hxx 
b/xmloff/source/text/XMLTextListBlockContext.hxx
index 9446ee5e90b4..4b18d625cc36 100644
--- a/xmloff/source/text/XMLTextListBlockContext.hxx
+++ b/xmloff/source/text/XMLTextListBlockContext.hxx
@@ -65,6 +65,8 @@ public:
     bool IsRestartNumbering() const { return mbRestartNumbering; }
     void ResetRestartNumbering() { mbRestartNumbering = false; }
 
+    /// does this list have (possibly inherited from parent) list-style-name?
+    bool HasListStyleName() { return !msListStyleName.isEmpty(); }
     const css::uno::Reference < css::container::XIndexReplace >& GetNumRules() 
const
         { return mxNumRules; }
 
diff --git a/xmloff/source/text/txtimp.cxx b/xmloff/source/text/txtimp.cxx
index e9858e31a722..f699b8b22379 100644
--- a/xmloff/source/text/txtimp.cxx
+++ b/xmloff/source/text/txtimp.cxx
@@ -1084,12 +1084,21 @@ OUString XMLTextImportHelper::SetStyleAndAttrs(
         OUString sListId;
         sal_Int16 nStartValue(-1);
         bool bNumberingIsNumber(true);
+        // Assure that list style of automatic paragraph style is applied at 
paragraph. (#i101349#)
+        bool bApplyNumRules(pStyle && pStyle->IsListStyleSet());
 
         if (pListBlock) {
+            // the xNumRules is always created, even without a list-style-name
+            if (pListBlock->HasListStyleName()
+                || (pListItem != nullptr && pListItem->HasNumRulesOverride()))
+            {
+                bApplyNumRules = true; // tdf#114287
+            }
 
             if (!pListItem) {
                 bNumberingIsNumber = false; // list-header
             }
+
             // consider text:style-override property of <text:list-item>
             xNewNumRules.set(
                 (pListItem != nullptr && pListItem->HasNumRulesOverride())
@@ -1116,8 +1125,6 @@ OUString XMLTextImportHelper::SetStyleAndAttrs(
 
         if (pListBlock || pNumberedParagraph)
         {
-            // Assure that list style of automatic paragraph style is applied 
at paragraph. (#i101349#)
-            bool bApplyNumRules = pStyle && pStyle->IsListStyleSet();
             if ( !bApplyNumRules )
             {
                 bool bSameNumRules = xNewNumRules == xNumRules;

Reply via email to