include/xmloff/txtimp.hxx                                       |    2 
 include/xmloff/xmltoken.hxx                                     |    1 
 schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng     |    9 +
 sw/qa/extras/odfexport/data/ParagraphMarkerMarkup.fodt          |   22 +++
 sw/qa/extras/odfexport/odfexport2.cxx                           |   10 +
 sw/qa/extras/odfimport/data/emptyParagraphLoosesFontHeight.fodt |   21 ++
 sw/qa/extras/odfimport/odfimport.cxx                            |   21 ++
 sw/qa/extras/ooxmlexport/ooxmlexport2.cxx                       |    3 
 sw/source/core/unocore/unoobj.cxx                               |   71 
+---------
 sw/source/core/unocore/unoparagraph.cxx                         |   15 ++
 sw/source/core/unocore/unoportenum.cxx                          |    5 
 xmloff/inc/xmlprop.hxx                                          |    1 
 xmloff/source/core/xmltoken.cxx                                 |    1 
 xmloff/source/text/txtimp.cxx                                   |    9 +
 xmloff/source/text/txtparae.cxx                                 |   32 ++++
 xmloff/source/text/txtparai.cxx                                 |   22 ++-
 xmloff/source/text/txtparai.hxx                                 |    1 
 xmloff/source/text/txtprmap.cxx                                 |    2 
 xmloff/source/token/tokens.txt                                  |    1 
 19 files changed, 181 insertions(+), 68 deletions(-)

New commits:
commit 1a88efa8e02a6d765dab13c7110443bb9e6acecf
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Wed May 10 20:39:12 2023 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu May 11 18:06:02 2023 +0200

    tdf#155238: Reimplement how ListAutoFormat is stored to ODF
    
    This reimplements commits 6249858a8972aef077e0249bd93cfe8f01bce4d6
    (sw: ODT import/export of DOCX's paragraph marker formatting,
    2022-12-19) and 209dce614c43f63f63f5b42a746665c0ec1cbfe3 (sw: fix
    ODT import of paragraph marker formatting, 2022-12-20).
    
    Instead of using an empty trailing span for the ListAutoFormat data,
    introduce a new loext:marker-style-name attribute for text:p element,
    referencing a text autostyle.
    
    The problems with the previous implementation were that (1) it was
    impossible (or very difficult) to disambiguate several empty trailing
    spans, in case it was needed; and (2) this was incompatible change,
    with other ODF implementations treating the trailing span normally.
    
    I couldn't manage to incorporate the attribute to paragraph autostyle,
    because of problems referencing different autostyles one from another,
    so put it directly to the paragraph attributes.
    
    Change-Id: I33473147f1f774c24cbbc57bf0c4f3a1d83ce5bc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151645
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/include/xmloff/txtimp.hxx b/include/xmloff/txtimp.hxx
index cc617393e1b4..218db6fa7acd 100644
--- a/include/xmloff/txtimp.hxx
+++ b/include/xmloff/txtimp.hxx
@@ -223,6 +223,8 @@ public:
             const OUString& rName ) const;
     XMLPropStyleContext* FindPageMaster(
             const OUString& rName ) const;
+    XMLPropStyleContext* FindAutoCharStyle(const OUString& rName) const;
+
     XMLPropStyleContext* FindDrawingPage(OUString const& rName) const;
 
     const css::uno::Reference< css::container::XNameContainer> & 
GetParaStyles() const;
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 09bb105d17e9..7f4f21c15dfc 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -1209,6 +1209,7 @@ namespace xmloff::token {
         XML_LINKED_CELL,
         XML_LINK_TO_SOURCE_DATA,
         XML_LIST,
+        XML_MARKER_STYLE_NAME,
         XML_LIST_BLOCK,
         XML_LIST_HEADER,
         XML_LIST_INFO,
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index c0a983f46aab..0436448644bb 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -3562,6 +3562,15 @@ 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
     </rng:optional>
   </rng:define>
 
+  <!-- TODO no proposal -->
+  <rng:define name="paragraph-attrs" combine="interleave">
+    <rng:optional>
+      <rng:attribute name="loext:marker-style-name">
+        <rng:ref name="styleNameRef"/>
+      </rng:attribute>
+    </rng:optional>
+  </rng:define>
+
   <!-- Belongs to project MCGR (Armin Le Grand) LO 7.6
        Intended to be used for theme colors too  -->
   <rng:define name="common-complex-color-attributes">
diff --git a/sw/qa/extras/odfexport/data/ParagraphMarkerMarkup.fodt 
b/sw/qa/extras/odfexport/data/ParagraphMarkerMarkup.fodt
new file mode 100644
index 000000000000..c3a21261da26
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/ParagraphMarkerMarkup.fodt
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:styles>
+  <style:style style:name="Standard" style:family="paragraph" 
style:class="text">
+   <style:text-properties fo:font-size="11pt"/>
+  </style:style>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="T1" style:family="text">
+   <style:text-properties fo:font-size="8pt"/>
+  </style:style>
+  <style:style style:name="T2" style:family="text">
+   <style:text-properties fo:font-size="9pt" fo:color="#ff0000"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:p text:style-name="Standard" loext:marker-style-name="T2"><text:span 
text:style-name="T1">text</text:span></text:p>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/odfexport/odfexport2.cxx 
b/sw/qa/extras/odfexport/odfexport2.cxx
index 269525a8756b..7c3d7fb9b841 100644
--- a/sw/qa/extras/odfexport/odfexport2.cxx
+++ b/sw/qa/extras/odfexport/odfexport2.cxx
@@ -1061,6 +1061,16 @@ DECLARE_ODFEXPORT_TEST(testTdf78510, "WordTest_edit.odt")
 #endif
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testParagraphMarkerMarkupRoundtrip)
+{
+    loadAndReload("ParagraphMarkerMarkup.fodt");
+    // Test that the markup stays at save-and-reload
+    xmlDocUniquePtr pXmlDoc = parseExport("content.xml");
+    assertXPath(pXmlDoc, 
"/office:document-content/office:body/office:text/text:p", "marker-style-name", 
"T2");
+    assertXPath(pXmlDoc, 
"/office:document-content/office:automatic-styles/style:style[@style:name='T2']/style:text-properties",
 "font-size", "9pt");
+    assertXPath(pXmlDoc, 
"/office:document-content/office:automatic-styles/style:style[@style:name='T2']/style:text-properties",
 "color", "#ff0000");
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/odfimport/data/emptyParagraphLoosesFontHeight.fodt 
b/sw/qa/extras/odfimport/data/emptyParagraphLoosesFontHeight.fodt
new file mode 100644
index 000000000000..7843d7e00f5f
--- /dev/null
+++ b/sw/qa/extras/odfimport/data/emptyParagraphLoosesFontHeight.fodt
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:styles>
+  <style:style style:name="Standard" style:family="paragraph" 
style:class="text">
+   <style:text-properties fo:font-size="11pt"/>
+  </style:style>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="T1" style:family="text">
+   <style:text-properties fo:font-size="8pt"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:p text:style-name="Standard"><text:span 
text:style-name="T1">value1</text:span><text:span 
text:style-name="T1"/></text:p>
+   <text:p text:style-name="Standard"><text:span 
text:style-name="T1"></text:span><text:span text:style-name="T1"/></text:p>
+   <text:p text:style-name="Standard"><text:span 
text:style-name="T1">value2</text:span><text:span 
text:style-name="T1"/></text:p>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/odfimport/odfimport.cxx 
b/sw/qa/extras/odfimport/odfimport.cxx
index 7225be2d4b8e..29df94d9afd6 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -1513,5 +1513,26 @@ CPPUNIT_TEST_FIXTURE(Test, testWindowsFileZone)
 #endif
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testEmptyTrailingSpans)
+{
+    createSwDoc("emptyParagraphLoosesFontHeight.fodt");
+
+    CPPUNIT_ASSERT_EQUAL(3, getParagraphs());
+
+    auto xPara2 = getParagraph(2);
+    CPPUNIT_ASSERT_EQUAL(float(11), getProperty<float>(xPara2, "CharHeight"));
+    auto xRun = getRun(xPara2, 1);
+    CPPUNIT_ASSERT_EQUAL(float(8), getProperty<float>(xRun, "CharHeight"));
+    // Both empty spans merge -> no more runs
+    CPPUNIT_ASSERT_THROW(getRun(xPara2, 2), 
css::container::NoSuchElementException);
+
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+    auto height1 = getXPath(pXmlDoc, "/root/page/body/txt[1]/infos/bounds", 
"height").toInt32();
+    auto height2 = getXPath(pXmlDoc, "/root/page/body/txt[2]/infos/bounds", 
"height").toInt32();
+    CPPUNIT_ASSERT_EQUAL(height1, height2);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(184, height2, 1); // allow a bit of room for 
rounding just in case
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx
index 8a816ae9f9dd..9248670760ac 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx
@@ -861,8 +861,7 @@ DECLARE_OOXMLEXPORT_TEST(testFdo64238_b, "fdo64238_b.docx")
         xRunEnum->nextElement();
         numOfRuns++;
     }
-    // "This is the ", "ODD", " [", "LEFT", "] header" and the colored 
paragraph marker
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), numOfRuns);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), numOfRuns);
 }
 
 DECLARE_OOXMLEXPORT_TEST(testFdo56679, "fdo56679.docx")
diff --git a/sw/source/core/unocore/unoobj.cxx 
b/sw/source/core/unocore/unoobj.cxx
index 7ef11b9462ab..2e65cf97bfcd 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -230,57 +230,6 @@ lcl_setAutoStyle(IStyleAccess & rStyleAccess, const 
uno::Any & rValue,
     rSet.Put(aFormat);
 };
 
-/// Tries to map rValue to RES_PARATR_LIST_AUTOFMT on the current paragraph, 
returns true on
-/// success.
-static bool lcl_setListAutoStyle(SwPaM& rPam, const uno::Any& rValue, 
SfxItemSet& rItemSet)
-{
-    // See if this is an empty range at the end of a paragraph.
-    if (rPam.Start()->GetNodeIndex() != rPam.End()->GetNodeIndex())
-    {
-        return false;
-    }
-
-    if (rPam.Start()->GetContentIndex() != rPam.End()->GetContentIndex())
-    {
-        return false;
-    }
-
-    SwTextNode* pTextNode = rPam.GetPointNode().GetTextNode();
-    if (!pTextNode)
-    {
-        return false;
-    }
-
-    if (rPam.Start()->GetContentIndex() != pTextNode->Len())
-    {
-        return false;
-    }
-
-    // Look up the style content based on the name.
-    OUString sStyle;
-    if (!(rValue >>= sStyle))
-    {
-        return false;
-    }
-
-    IStyleAccess& rStyleAccess = rPam.GetDoc().GetIStyleAccess();
-    std::shared_ptr<SfxItemSet> pStyle
-        = rStyleAccess.getByName(sStyle, IStyleAccess::AUTO_STYLE_CHAR);
-    if (!pStyle)
-    {
-        return false;
-    }
-
-    // Set the style on the text node.
-    SwFormatAutoFormat aItem(RES_PARATR_LIST_AUTOFMT);
-    aItem.SetStyleHandle(pStyle);
-    pTextNode->SetAttr(aItem);
-    // Clear the style from the hints array. Without clearing, it would 
contain some style which
-    // happened to be there previously.
-    rItemSet.ClearItem(RES_TXTATR_AUTOFMT);
-    return true;
-}
-
 void
 SwUnoCursorHelper::SetTextFormatColl(const uno::Any & rAny, SwPaM & rPaM)
 {
@@ -499,11 +448,6 @@ SwUnoCursorHelper::SetCursorPropertyValue(
             lcl_setCharStyle(rPam.GetDoc(), rValue, rItemSet);
         break;
         case RES_TXTATR_AUTOFMT:
-            if (lcl_setListAutoStyle(rPam, rValue, rItemSet))
-            {
-                break;
-            }
-
             lcl_setAutoStyle(rPam.GetDoc().GetIStyleAccess(),
                     rValue, rItemSet, false);
         break;
@@ -567,8 +511,8 @@ SwUnoCursorHelper::SetCursorPropertyValue(
             }
             else if (FN_UNO_PARA_NUM_AUTO_FORMAT == rEntry.nWID)
             {
-                uno::Sequence<beans::NamedValue> props;
-                if (rValue >>= props)
+                std::shared_ptr<SfxItemSet> pAutoStyle;
+                if (uno::Sequence<beans::NamedValue> props; rValue >>= props)
                 {
                     // TODO create own map for this, it contains 
UNO_NAME_DISPLAY_NAME? or make property readable so ODF export can map it to a 
automatic style?
                     SfxItemPropertySet const& 
rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE));
@@ -603,8 +547,15 @@ SwUnoCursorHelper::SetCursorPropertyValue(
 
                     IStyleAccess& rStyleAccess = 
rPam.GetDoc().GetIStyleAccess();
                     // Add it to the autostyle pool, needed by the ODT export.
-                    const std::shared_ptr<SfxItemSet> pAutoStyle
-                        = rStyleAccess.getAutomaticStyle(items, 
IStyleAccess::AUTO_STYLE_CHAR);
+                    pAutoStyle = rStyleAccess.getAutomaticStyle(items, 
IStyleAccess::AUTO_STYLE_CHAR);
+                }
+                else if (OUString styleName; rValue >>= styleName)
+                {
+                    IStyleAccess& rStyleAccess = 
rPam.GetDoc().GetIStyleAccess();
+                    pAutoStyle = rStyleAccess.getByName(styleName, 
IStyleAccess::AUTO_STYLE_CHAR);
+                }
+                if (pAutoStyle)
+                {
                     SwFormatAutoFormat item(RES_PARATR_LIST_AUTOFMT);
                     // note: paragraph auto styles have ParaStyleName property 
for the parent style; character auto styles currently do not because there's a 
separate hint, but for this it would be a good way to add it in order to export 
it as style:parent-style-name, see XMLTextParagraphExport::Add()
                     item.SetStyleHandle(pAutoStyle);
diff --git a/sw/source/core/unocore/unoparagraph.cxx 
b/sw/source/core/unocore/unoparagraph.cxx
index 55c71ca730a4..1d0fae809f41 100644
--- a/sw/source/core/unocore/unoparagraph.cxx
+++ b/sw/source/core/unocore/unoparagraph.cxx
@@ -26,6 +26,7 @@
 #include <comphelper/diagnose_ex.hxx>
 
 #include <cmdid.h>
+#include <fmtautofmt.hxx>
 #include <unomid.h>
 #include <unoparaframeenum.hxx>
 #include <unotext.hxx>
@@ -527,6 +528,20 @@ uno::Sequence< uno::Any > 
SwXParagraph::Impl::GetPropertyValues_Impl(
     const SwAttrSet& rAttrSet( rTextNode.GetSwAttrSet() );
     for (sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); nProp++)
     {
+        if (pPropertyNames[nProp] == "ParaMarkerAutoStyleSpan")
+        {
+            // A hack to tunnel the fake text span to ODF export
+            // see XMLTextParagraphExport::exportParagraph
+            if (rTextNode.GetAttr(RES_PARATR_LIST_AUTOFMT).GetStyleHandle())
+            {
+                SwUnoCursor aEndCursor(*aPam.GetMark());
+                css::uno::Reference<css::beans::XPropertySet> xFakeSpan(
+                    new SwXTextPortion(&aEndCursor, {}, PORTION_LIST_AUTOFMT));
+                pValues[nProp] <<= xFakeSpan;
+            }
+            continue;
+        }
+
         SfxItemPropertyMapEntry const*const pEntry =
             rMap.getByName( pPropertyNames[nProp] );
         if (!pEntry)
diff --git a/sw/source/core/unocore/unoportenum.cxx 
b/sw/source/core/unocore/unoportenum.cxx
index db567f3cbf05..fd6cc626336b 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -1504,11 +1504,6 @@ static void lcl_CreatePortions(
             // text portion because there may be a hyperlink attribute
             xRef = new SwXTextPortion(pUnoCursor, i_xParentText, PORTION_TEXT);
         }
-        else if (bAtEnd && !xRef.is() && 
pTextNode->GetSwAttrSet().HasItem(RES_PARATR_LIST_AUTOFMT))
-        {
-            // We have explicit paragraph marker formatting, export it.
-            xRef = new SwXTextPortion(pUnoCursor, i_xParentText, 
PORTION_LIST_AUTOFMT);
-        }
         else if (bAtEnd && !xRef.is() && pHints)
         {
             // See if there is an empty autofmt at the paragraph end. If so, 
export it, since that
diff --git a/xmloff/inc/xmlprop.hxx b/xmloff/inc/xmlprop.hxx
index b93bf926e569..e2968b688e2c 100644
--- a/xmloff/inc/xmlprop.hxx
+++ b/xmloff/inc/xmlprop.hxx
@@ -428,6 +428,7 @@ inline constexpr OUStringLiteral PROP_LineTransparence = 
u"LineTransparence";
 inline constexpr OUStringLiteral PROP_LineWidth = u"LineWidth";
 inline constexpr OUStringLiteral PROP_Lines = u"Lines";
 inline constexpr OUStringLiteral PROP_LinkNumberFormatToSource = 
u"LinkNumberFormatToSource";
+inline constexpr OUStringLiteral PROP_ListAutoFormat = u"ListAutoFormat";
 inline constexpr OUStringLiteral PROP_Logarithmic = u"Logarithmic";
 inline constexpr OUStringLiteral PROP_MajorOrigin = u"MajorOrigin";
 inline constexpr OUStringLiteral PROP_MarkPosition = u"MarkPosition";
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index e0189451803b..b35fa86b9ef3 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -1222,6 +1222,7 @@ namespace xmloff::token {
         TOKEN( "linked-cell",                     XML_LINKED_CELL ),
         TOKEN( "link-to-source-data",             XML_LINK_TO_SOURCE_DATA ),
         TOKEN( "list",                            XML_LIST ),
+        TOKEN( "marker-style-name",               XML_MARKER_STYLE_NAME ),
         TOKEN( "list-block",                      XML_LIST_BLOCK ),
         TOKEN( "list-header",                     XML_LIST_HEADER ),
         TOKEN( "list-info",                       XML_LIST_INFO ),
diff --git a/xmloff/source/text/txtimp.cxx b/xmloff/source/text/txtimp.cxx
index f699b8b22379..b31c2b6ab99b 100644
--- a/xmloff/source/text/txtimp.cxx
+++ b/xmloff/source/text/txtimp.cxx
@@ -2037,6 +2037,15 @@ XMLPropStyleContext* XMLTextImportHelper::FindPageMaster(
     return pStyle;
 }
 
+XMLPropStyleContext* XMLTextImportHelper::FindAutoCharStyle(const OUString& 
rName) const
+{
+    if (!m_xImpl->m_xAutoStyles)
+        return nullptr;
+    auto pStyle
+        = 
m_xImpl->m_xAutoStyles->FindStyleChildContext(XmlStyleFamily::TEXT_TEXT, rName, 
true);
+    return 
dynamic_cast<XMLPropStyleContext*>(const_cast<SvXMLStyleContext*>(pStyle));
+}
+
 XMLPropStyleContext * XMLTextImportHelper::FindDrawingPage(OUString const& 
rName) const
 {
     if (!m_xImpl->m_xAutoStyles.is())
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index 65faad9b324d..d621d2c75cd6 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -32,6 +32,7 @@
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/beans/XMultiPropertySet.hpp>
 #include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
 #include <com/sun/star/graphic/XGraphic.hpp>
 #include <com/sun/star/text/XTextDocument.hpp>
 #include <com/sun/star/text/XTextSectionsSupplier.hpp>
@@ -2187,6 +2188,37 @@ void XMLTextParagraphExport::exportParagraph(
                 }
             }
         }
+
+        if (GetExport().getSaneDefaultVersion() & 
SvtSaveOptions::ODFSVER_EXTENDED)
+        {
+            try
+            {
+                // ParaMarkerAutoStyleSpan is a hidden property, just to pass 
the autostyle here
+                // See SwXParagraph::Impl::GetPropertyValues_Impl
+                css::uno::Any aVal = 
xPropSet->getPropertyValue("ParaMarkerAutoStyleSpan");
+                if (auto xFakeSpan = aVal.query<css::beans::XPropertySet>())
+                {
+                    if (bAutoStyles)
+                    {
+                        Add(XmlStyleFamily::TEXT_TEXT, xFakeSpan);
+                    }
+                    else
+                    {
+                        bool bIsUICharStyle, bHasAutoStyle;
+                        OUString sStyle = FindTextStyle(xFakeSpan, 
bIsUICharStyle, bHasAutoStyle);
+                        if (!sStyle.isEmpty())
+                        {
+                            GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, 
XML_MARKER_STYLE_NAME,
+                                                     sStyle);
+                        }
+                    }
+                }
+            }
+            catch (const css::beans::UnknownPropertyException&)
+            {
+                // No problem
+            }
+        }
     }
 
     Reference < XEnumerationAccess > xEA( rTextContent, UNO_QUERY );
diff --git a/xmloff/source/text/txtparai.cxx b/xmloff/source/text/txtparai.cxx
index 5fffc202612a..bf905114a89c 100644
--- a/xmloff/source/text/txtparai.cxx
+++ b/xmloff/source/text/txtparai.cxx
@@ -41,6 +41,7 @@
 
 #include <sax/tools/converter.hxx>
 
+#include <xmloff/prstylei.hxx>
 #include <xmloff/xmlictxt.hxx>
 #include <xmloff/xmlimp.hxx>
 #include <xmloff/xmltoken.hxx>
@@ -1675,6 +1676,10 @@ XMLParaContext::XMLParaContext(
                 nStartValue = sal::static_int_cast< sal_Int16 
>(aIter.toInt32());
             }
             break;
+        case XML_ELEMENT(LO_EXT, XML_MARKER_STYLE_NAME):
+            if (auto pStyle = 
rImport.GetTextImport()->FindAutoCharStyle(aIter.toString()))
+                m_aMarkerStyleName = pStyle->GetAutoName();
+            break;
         default:
             XMLOFF_WARN_UNKNOWN("xmloff", aIter);
         }
@@ -1720,6 +1725,21 @@ void XMLParaContext::endFastElement(sal_Int32 )
     // insert a paragraph break
     xTxtImport->InsertControlCharacter( ControlCharacter::APPEND_PARAGRAPH );
 
+    if (m_aMarkerStyleName.hasValue())
+    {
+        if (auto xPropSet = xStart.query<css::beans::XPropertySet>())
+        {
+            try
+            {
+                xPropSet->setPropertyValue("ListAutoFormat", 
m_aMarkerStyleName);
+            }
+            catch (const css::beans::UnknownPropertyException&)
+            {
+                // no problem
+            }
+        }
+    }
+
     // create a cursor that select the whole last paragraph
     Reference < XTextCursor > xAttrCursor;
     try {
@@ -1832,7 +1852,7 @@ void XMLParaContext::endFastElement(sal_Int32 )
     {
         bool bSetNoFormatAttr = false;
         uno::Reference<beans::XPropertySet> xCursorProps(xAttrCursor, 
uno::UNO_QUERY);
-        if (m_xHints->GetHints().size() > 1)
+        if (m_xHints->GetHints().size() > 1 || m_aMarkerStyleName.hasValue())
         {
             // We have multiple hints, then make try to ask the cursor to not 
upgrade our character
             // attributes to paragraph-level formatting, which would lead to 
incorrect rendering.
diff --git a/xmloff/source/text/txtparai.hxx b/xmloff/source/text/txtparai.hxx
index 66c64181c4ba..fed2690cb429 100644
--- a/xmloff/source/text/txtparai.hxx
+++ b/xmloff/source/text/txtparai.hxx
@@ -42,6 +42,7 @@ class XMLParaContext : public SvXMLImportContext
     OUString             m_sProperty;
     OUString             m_sContent;
     OUString             m_sDatatype;
+    css::uno::Any        m_aMarkerStyleName;
     bool                 m_bHaveAbout;
     sal_Int8             nOutlineLevel;
     std::unique_ptr<XMLHints_Impl> m_xHints;
diff --git a/xmloff/source/text/txtprmap.cxx b/xmloff/source/text/txtprmap.cxx
index 0c2a04a1eec4..1151eef64575 100644
--- a/xmloff/source/text/txtprmap.cxx
+++ b/xmloff/source/text/txtprmap.cxx
@@ -463,6 +463,8 @@ XMLPropertyMapEntry constexpr aXMLParaPropMap[] =
 
     MP_ED( PROP_FontIndependentLineSpacing, STYLE, 
FONT_INDEPENDENT_LINE_SPACING, XML_TYPE_BOOL, 0 ),
 
+    MAP_EXT( PROP_ListAutoFormat, XML_NAMESPACE_LO_EXT, XML_MARKER_STYLE_NAME, 
XML_TYPE_STYLENAME|XML_TYPE_PROP_PARAGRAPH, 0 ),
+
     M_END()
 };
 
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index d1932e24e103..2fe53258a2f6 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -1122,6 +1122,7 @@ lines-used
 linked-cell
 link-to-source-data
 list
+marker-style-name
 list-block
 list-header
 list-info

Reply via email to