include/xmloff/txtparae.hxx                                   |    7 
 sc/sdi/cellsh.sdi                                             |    2 
 sc/source/ui/view/cellsh.cxx                                  |    1 
 sd/qa/unit/data/odp/tdf161023.fodp                            |   35 +
 sd/qa/unit/import-tests2.cxx                                  |   52 ++
 sw/qa/core/text/data/number-portion-format.odt                |binary
 sw/qa/extras/htmlexport/xhtmlexport.cxx                       |    4 
 sw/qa/extras/odfexport/data/table_in_frame_to_page.fodt       |   66 +++
 sw/qa/extras/odfexport/data/tdf160253_ordinary_numbering.fodt |   43 ++
 sw/qa/extras/odfexport/data/tdf160253_outline_numbering.fodt  |   37 +
 sw/qa/extras/odfexport/odfexport2.cxx                         |   84 +++-
 sw/qa/extras/odfimport/data/empty_line_in_text_box.fodt       |   31 +
 sw/qa/extras/odfimport/odfimport.cxx                          |   53 ++
 sw/qa/extras/ooxmlexport/data/A019_min.docx                   |binary
 sw/qa/extras/ooxmlexport/ooxmlexport19.cxx                    |   17 
 sw/source/core/text/txtfld.cxx                                |   22 -
 sw/source/filter/ww8/docxattributeoutput.cxx                  |   11 
 sw/source/filter/ww8/docxexport.hxx                           |    6 
 sw/source/filter/ww8/ww8par.cxx                               |   19 
 sw/source/filter/ww8/ww8par.hxx                               |    2 
 sw/source/filter/ww8/ww8par2.cxx                              |    4 
 sw/source/filter/ww8/ww8par5.cxx                              |    2 
 sw/source/filter/ww8/ww8par6.cxx                              |    4 
 sw/source/filter/xml/xmlfmte.cxx                              |    2 
 writerfilter/source/dmapper/PropertyMap.cxx                   |   11 
 xmloff/source/text/txtparae.cxx                               |  208 ++--------
 xmloff/source/text/txtparai.cxx                               |   13 
 27 files changed, 518 insertions(+), 218 deletions(-)

New commits:
commit 483bdc12b257e4860ae22bd4f6b468019d75aa4e
Author:     Mike Kaganski <[email protected]>
AuthorDate: Mon May 13 15:04:09 2024 +0500
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Jun 18 12:53:04 2024 +0200

    tdf#161054: drop support of last empty span as paragraph mark format
    
    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) introduced support for paragraph
    marker formatting in ODF, using an empty trailing span. Later, commit
    1a88efa8e02a6d765dab13c7110443bb9e6acecf (tdf#155238: Reimplement how
    ListAutoFormat is stored to ODF, 2023-05-11) changed how the data was
    stored in ODF. Then, in commit 69ed893087f89d176a5ec4b263ce8d75774be72b
    (tdf#160253: fix list identifier export decision code, 2024-04-24), some
    remnants of the older "trailing empty spans" were removed, but a code
    was added in XMLParaContext::endFastElement, to keep backward compatible
    with documents created in the frame between December 2022 and May 2023.
    
    The said compatibility code brings own problems, requiring new hacks
    like commit 2ca93eb5df7ddb8641ff7d884a109261c9700aca (tdf#161023: Empty
    spans may only define paragraph marks in text documents, 2024-05-13),
    and keeping the code would need more hacks on top, e.g. to fix the case
    in ODT documents.
    
    Instead, let's bite the bullet, and drop the compatibility with this
    initial implementation, because it was only a brief period during which
    the documents could be created, which can be affected by this drop. This
    makes the code simpler.
    
    A testdoc for testNumberPortionFormat was edited to use the new markup
    for the paragraph marks formatting.
    
    Change-Id: I053e72dd1cc2ead83baa6ce7d24c8522b494c8fa
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167583
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/sw/qa/core/text/data/number-portion-format.odt 
b/sw/qa/core/text/data/number-portion-format.odt
index 19b23ae84420..70b67ee3547e 100644
Binary files a/sw/qa/core/text/data/number-portion-format.odt and 
b/sw/qa/core/text/data/number-portion-format.odt differ
diff --git a/sw/qa/extras/odfimport/data/empty_line_in_text_box.fodt 
b/sw/qa/extras/odfimport/data/empty_line_in_text_box.fodt
new file mode 100644
index 000000000000..4ae36a9c5fac
--- /dev/null
+++ b/sw/qa/extras/odfimport/data/empty_line_in_text_box.fodt
@@ -0,0 +1,31 @@
+<?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:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+  <style:font-face style:name="Liberation Sans" 
svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="swiss" 
style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:default-style style:family="graphic">
+   <style:text-properties style:font-name="Liberation Sans" 
fo:font-size="18pt"/>
+  </style:default-style>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="T1" style:family="text">
+   <style:text-properties fo:font-size="10pt"/>
+  </style:style>
+  <style:style style:name="gr1" style:family="graphic">
+   <style:graphic-properties style:vertical-pos="from-top" 
style:vertical-rel="paragraph" style:horizontal-pos="from-left" 
style:horizontal-rel="paragraph"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:p text:style-name="Standard"><draw:frame text:anchor-type="paragraph" 
draw:name="TextFrame1" draw:style-name="gr1" svg:width="4cm" svg:x="4cm" 
svg:y="4cm">
+     <draw:text-box>
+      <text:p><text:span text:style-name="T1">a</text:span></text:p>
+      <text:p><text:span text:style-name="T1"/></text:p>
+      <text:p><text:span text:style-name="T1">c</text:span></text:p>
+     </draw:text-box>
+    </draw:frame></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 70c6452e3d9f..0074b53f851e 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -1561,5 +1561,58 @@ CPPUNIT_TEST_FIXTURE(Test, testBrokenPackage_Tdf159474)
     CPPUNIT_ASSERT_EQUAL(u"Empty document"_ustr, getParagraph(1)->getString());
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf161054)
+{
+    // Similar to testTdf161023 in sd/qa/unit/import-tests2.cxx
+    // Given a shape with three paragraphs (18pt), all directly assigned a 
smaller font (10pt)
+    createSwDoc("empty_line_in_text_box.fodt");
+    auto shapeText = getShape(1).queryThrow<text::XTextRange>()->getText();
+
+    // 1st paragraph, not empty
+    {
+        auto paragraph(getParagraphOfText(1, shapeText));
+        CPPUNIT_ASSERT_EQUAL(u"a"_ustr, paragraph->getString());
+        auto run(getRun(paragraph, 1));
+        CPPUNIT_ASSERT_EQUAL(u"a"_ustr, run->getString());
+        uno::Reference<beans::XPropertySet> xPropSet(run, 
uno::UNO_QUERY_THROW);
+        double fCharHeight = 0;
+        xPropSet->getPropertyValue("CharHeight") >>= fCharHeight;
+        CPPUNIT_ASSERT_EQUAL(10.0, fCharHeight);
+        // No more runs
+        CPPUNIT_ASSERT_THROW(getRun(paragraph, 2), 
container::NoSuchElementException);
+    }
+
+    // Empty 2nd paragraph, consisting of a single span: this span was treated 
as "paragraph mark"
+    {
+        auto paragraph(getParagraphOfText(2, shapeText));
+        CPPUNIT_ASSERT_EQUAL(u""_ustr, paragraph->getString());
+        auto run(getRun(paragraph, 1));
+        CPPUNIT_ASSERT_EQUAL(u""_ustr, run->getString());
+        uno::Reference<beans::XPropertySet> xPropSet(run, 
uno::UNO_QUERY_THROW);
+        double fCharHeight = 0;
+        xPropSet->getPropertyValue("CharHeight") >>= fCharHeight;
+        // Without the fix, this would fail with
+        // - Expected: 10
+        // - Actual  : 18
+        CPPUNIT_ASSERT_EQUAL(10.0, fCharHeight);
+        // No more runs
+        CPPUNIT_ASSERT_THROW(getRun(paragraph, 2), 
container::NoSuchElementException);
+    }
+
+    // 3rd paragraph, not empty
+    {
+        auto paragraph(getParagraphOfText(3, shapeText));
+        CPPUNIT_ASSERT_EQUAL(u"c"_ustr, paragraph->getString());
+        auto run(getRun(paragraph, 1));
+        CPPUNIT_ASSERT_EQUAL(u"c"_ustr, run->getString());
+        uno::Reference<beans::XPropertySet> xPropSet(run, 
uno::UNO_QUERY_THROW);
+        double fCharHeight = 0;
+        xPropSet->getPropertyValue("CharHeight") >>= fCharHeight;
+        CPPUNIT_ASSERT_EQUAL(10.0, fCharHeight);
+        // No more runs
+        CPPUNIT_ASSERT_THROW(getRun(paragraph, 2), 
container::NoSuchElementException);
+    }
+}
+
 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 435f08d5101d..9656ba081902 100644
--- a/xmloff/source/text/txtparai.cxx
+++ b/xmloff/source/text/txtparai.cxx
@@ -34,7 +34,6 @@
 #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/XTextDocument.hpp>
 #include <com/sun/star/text/XTextRangeCompare.hpp>
 #include <com/sun/star/container/XIndexReplace.hpp>
 #include <com/sun/star/drawing/XShapes.hpp>
@@ -1793,48 +1792,6 @@ void XMLParaContext::endFastElement(sal_Int32 )
                                                true,
                                                mbOutlineContentVisible);
 
-    bool bEmptyHints = false;
-    XMLHint_Impl* pMarkerStyleHint = nullptr;
-    if (m_xHints)
-    {
-        uno::Reference<text::XTextRangeCompare> 
xCompare(xTxtImport->GetText(), uno::UNO_QUERY);
-        if (xCompare.is())
-        {
-            bool bTextDocument = 
GetImport().GetModel().query<XTextDocument>().is();
-            try
-            {
-                for (const auto& pHint : m_xHints->GetHints())
-                {
-                    if (xCompare->compareRegionStarts(pHint->GetStart(), 
pHint->GetEnd()) == 0)
-                    {
-                        bEmptyHints = true;
-
-                        // Is this the trailing empty span, defining the 
paragraph mark properties?
-                        // Convert it to the marker style, for backward 
compatibility with documents
-                        // created between commits 
6249858a8972aef077e0249bd93cfe8f01bce4d6 and
-                        // 1a88efa8e02a6d765dab13c7110443bb9e6acecf, where the 
trailing empty spans
-                        // were used to store the marker formatting
-                        if (bTextDocument && pHint->GetType() == 
XMLHintType::XML_HINT_STYLE
-                            && !m_aMarkerStyleName.hasValue()
-                            && 
xCompare->compareRegionStarts(pHint->GetStart(), xEnd) == 0)
-                        {
-                            if (auto pStyle = 
GetImport().GetTextImport()->FindAutoCharStyle(
-                                    
static_cast<XMLStyleHint_Impl*>(pHint.get())->GetStyleName()))
-                            {
-                                m_aMarkerStyleName = pStyle->GetAutoName();
-                                pMarkerStyleHint = pHint.get();
-                            }
-                        }
-                    }
-                }
-            }
-            catch (const uno::Exception&)
-            {
-                TOOLS_WARN_EXCEPTION("xmloff.text", "");
-            }
-        }
-    }
-
     if (m_aMarkerStyleName.hasValue())
     {
         if (auto xPropSet = xStart.query<css::beans::XPropertySet>())
@@ -1894,6 +1851,24 @@ void XMLParaContext::endFastElement(sal_Int32 )
 
     if (m_xHints)
     {
+        bool bEmptyHints = false;
+        if (auto xCompare = 
xTxtImport->GetText().query<text::XTextRangeCompare>())
+        {
+            try
+            {
+                for (const auto& pHint : m_xHints->GetHints())
+                {
+                    if (xCompare->compareRegionStarts(pHint->GetStart(), 
pHint->GetEnd()) == 0)
+                    {
+                        bEmptyHints = true;
+                    }
+                }
+            }
+            catch (const uno::Exception&)
+            {
+                TOOLS_WARN_EXCEPTION("xmloff.text", "");
+            }
+        }
         bool bSetNoFormatAttr = false;
         uno::Reference<beans::XPropertySet> xCursorProps(xAttrCursor, 
uno::UNO_QUERY);
         if (bEmptyHints || m_aMarkerStyleName.hasValue())
@@ -1915,7 +1890,6 @@ void XMLParaContext::endFastElement(sal_Int32 )
             switch( pHint->GetType() )
             {
             case XMLHintType::XML_HINT_STYLE:
-                if (pHint != pMarkerStyleHint) // already processed above
                 {
                     const OUString& rStyleName =
                             static_cast<XMLStyleHint_Impl 
*>(pHint)->GetStyleName();
commit 0474804b455f26d54909c05c8d9b8bf5b49992ea
Author:     Mike Kaganski <[email protected]>
AuthorDate: Sun May 12 22:53:23 2024 +0500
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Jun 18 12:53:04 2024 +0200

    tdf#161023: Empty spans may only define paragraph marks in text documents
    
    Change-Id: I40607652a0fd8e31c609732daa54bb796e3fffa0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167557
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/sd/qa/unit/data/odp/tdf161023.fodp 
b/sd/qa/unit/data/odp/tdf161023.fodp
new file mode 100644
index 000000000000..bf3a894cec4b
--- /dev/null
+++ b/sd/qa/unit/data/odp/tdf161023.fodp
@@ -0,0 +1,35 @@
+<?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:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
office:version="1.3" 
office:mimetype="application/vnd.oasis.opendocument.presentation">
+ <office:font-face-decls>
+  <style:font-face style:name="Liberation Sans" 
svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="roman" 
style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:style style:name="standard" style:family="graphic">
+   <style:text-properties style:font-name="Liberation Sans" 
fo:font-size="18pt"/>
+  </style:style>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="T1" style:family="text">
+   <style:text-properties fo:font-size="10pt"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:master-styles>
+  <draw:layer-set>
+   <draw:layer draw:name="layout"/>
+  </draw:layer-set>
+ </office:master-styles>
+ <office:body>
+  <office:presentation>
+   <draw:page draw:name="page1">
+    <draw:frame draw:layer="layout" svg:width="4cm" svg:x="4cm" svg:y="4cm">
+     <draw:text-box>
+      <text:p><text:span text:style-name="T1">a</text:span></text:p>
+      <text:p><text:span text:style-name="T1"/></text:p>
+      <text:p><text:span text:style-name="T1">c</text:span></text:p>
+     </draw:text-box>
+    </draw:frame>
+   </draw:page>
+  </office:presentation>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx
index ac730a24d6bf..a69a30ef991a 100644
--- a/sd/qa/unit/import-tests2.cxx
+++ b/sd/qa/unit/import-tests2.cxx
@@ -1982,6 +1982,58 @@ CPPUNIT_TEST_FIXTURE(SdImportTest2, testMasterSlides)
     CPPUNIT_ASSERT_EQUAL(sal_Int32(7), xMasterPages->getCount());
 }
 
+CPPUNIT_TEST_FIXTURE(SdImportTest2, testTdf161023)
+{
+    // Given a shape with three paragraphs (18pt), all directly assigned a 
smaller font (10pt)
+    createSdImpressDoc("odp/tdf161023.fodp");
+    auto shape = getShapeFromPage(0, 0);
+
+    // 1st paragraph, not empty
+    {
+        auto paragraph(getParagraphFromShape(0, shape));
+        CPPUNIT_ASSERT_EQUAL(u"a"_ustr, paragraph->getString());
+        auto run(getRunFromParagraph(0, paragraph));
+        CPPUNIT_ASSERT_EQUAL(u"a"_ustr, run->getString());
+        uno::Reference<beans::XPropertySet> xPropSet(run, 
uno::UNO_QUERY_THROW);
+        double fCharHeight = 0;
+        xPropSet->getPropertyValue("CharHeight") >>= fCharHeight;
+        CPPUNIT_ASSERT_EQUAL(10.0, fCharHeight);
+        // No more runs
+        CPPUNIT_ASSERT_THROW(getRunFromParagraph(1, paragraph), 
container::NoSuchElementException);
+    }
+
+    // Empty 2nd paragraph, consisting of a single span: this span was treated 
as "paragraph mark"
+    {
+        auto paragraph(getParagraphFromShape(1, shape));
+        CPPUNIT_ASSERT_EQUAL(u""_ustr, paragraph->getString());
+        auto run(getRunFromParagraph(0, paragraph));
+        CPPUNIT_ASSERT_EQUAL(u""_ustr, run->getString());
+        uno::Reference<beans::XPropertySet> xPropSet(run, 
uno::UNO_QUERY_THROW);
+        double fCharHeight = 0;
+        xPropSet->getPropertyValue("CharHeight") >>= fCharHeight;
+        // Without the fix, this would fail with
+        // - Expected: 10
+        // - Actual  : 18
+        CPPUNIT_ASSERT_EQUAL(10.0, fCharHeight);
+        // No more runs
+        CPPUNIT_ASSERT_THROW(getRunFromParagraph(1, paragraph), 
container::NoSuchElementException);
+    }
+
+    // 3rd paragraph, not empty
+    {
+        auto paragraph(getParagraphFromShape(2, shape));
+        CPPUNIT_ASSERT_EQUAL(u"c"_ustr, paragraph->getString());
+        auto run(getRunFromParagraph(0, paragraph));
+        CPPUNIT_ASSERT_EQUAL(u"c"_ustr, run->getString());
+        uno::Reference<beans::XPropertySet> xPropSet(run, 
uno::UNO_QUERY_THROW);
+        double fCharHeight = 0;
+        xPropSet->getPropertyValue("CharHeight") >>= fCharHeight;
+        CPPUNIT_ASSERT_EQUAL(10.0, fCharHeight);
+        // No more runs
+        CPPUNIT_ASSERT_THROW(getRunFromParagraph(1, paragraph), 
container::NoSuchElementException);
+    }
+}
+
 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 b46cdafb49f9..435f08d5101d 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/XTextDocument.hpp>
 #include <com/sun/star/text/XTextRangeCompare.hpp>
 #include <com/sun/star/container/XIndexReplace.hpp>
 #include <com/sun/star/drawing/XShapes.hpp>
@@ -1799,6 +1800,7 @@ void XMLParaContext::endFastElement(sal_Int32 )
         uno::Reference<text::XTextRangeCompare> 
xCompare(xTxtImport->GetText(), uno::UNO_QUERY);
         if (xCompare.is())
         {
+            bool bTextDocument = 
GetImport().GetModel().query<XTextDocument>().is();
             try
             {
                 for (const auto& pHint : m_xHints->GetHints())
@@ -1812,7 +1814,8 @@ void XMLParaContext::endFastElement(sal_Int32 )
                         // created between commits 
6249858a8972aef077e0249bd93cfe8f01bce4d6 and
                         // 1a88efa8e02a6d765dab13c7110443bb9e6acecf, where the 
trailing empty spans
                         // were used to store the marker formatting
-                        if (!m_aMarkerStyleName.hasValue()
+                        if (bTextDocument && pHint->GetType() == 
XMLHintType::XML_HINT_STYLE
+                            && !m_aMarkerStyleName.hasValue()
                             && 
xCompare->compareRegionStarts(pHint->GetStart(), xEnd) == 0)
                         {
                             if (auto pStyle = 
GetImport().GetTextImport()->FindAutoCharStyle(
commit 63f50af47aec9850aaade5636949c013eebb6332
Author:     Mike Kaganski <[email protected]>
AuthorDate: Fri Apr 26 00:44:45 2024 +0500
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Jun 18 12:53:04 2024 +0200

    This block seems obsolete now, try to drop it
    
    ... and see if something breaks. Unit tests pass.
    Likely obsoleted by commit 69ed893087f89d176a5ec4b263ce8d75774be72b
    (tdf#160253: fix list identifier export decision code, 2024-04-24).
    
    Change-Id: I4fde19e1047104686df22053c9b140819ea72963
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166651
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index f9175e03d2c5..b7101765368d 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -1687,49 +1687,6 @@ void 
XMLTextParagraphExport::collectTextAutoStylesAndNodeExportOrder(bool bIsPro
             }
         }
 
-    Reference< XNumberingRulesSupplier > xNumberingRulesSupp( 
GetExport().GetModel(), UNO_QUERY );
-    if ( xNumberingRulesSupp.is() )
-    {
-        Reference< XIndexAccess > xNumberingRules = 
xNumberingRulesSupp->getNumberingRules();
-        sal_Int32 nCount = xNumberingRules->getCount();
-        // Custom outline assignment lost after re-importing sxw (#i73361#)
-        for( sal_Int32 i = 0; i < nCount; ++i )
-        {
-            Reference< XIndexReplace > xNumRule( xNumberingRules->getByIndex( 
i ), UNO_QUERY );
-            if( xNumRule.is() && xNumRule->getCount() )
-            {
-                Reference < XNamed > xNamed( xNumRule, UNO_QUERY );
-                OUString sName;
-                if( xNamed.is() )
-                    sName = xNamed->getName();
-                bool bAdd = sName.isEmpty();
-                if( !bAdd )
-                {
-                    Reference < XPropertySet > xNumPropSet( xNumRule,
-                                                            UNO_QUERY );
-                    if( xNumPropSet.is() &&
-                        xNumPropSet->getPropertySetInfo()
-                                   ->hasPropertyByName( "IsAutomatic" ) )
-                    {
-                        bAdd = 
*o3tl::doAccess<bool>(xNumPropSet->getPropertyValue( "IsAutomatic" ));
-                        // Check on outline style (#i73361#)
-                        if ( bAdd &&
-                             xNumPropSet->getPropertySetInfo()
-                                       ->hasPropertyByName( 
"NumberingIsOutline" ) )
-                        {
-                            bAdd = 
!(*o3tl::doAccess<bool>(xNumPropSet->getPropertyValue( "NumberingIsOutline" )));
-                        }
-                    }
-                    else
-                    {
-                        bAdd = true;
-                    }
-                }
-                if( bAdd )
-                    maListAutoPool.Add( xNumRule );
-            }
-        }
-    }
     mbCollected = true;
 }
 
commit 2d9998ae708c43cd38a7a23b1673fc5545f0e6f4
Author:     Mike Kaganski <[email protected]>
AuthorDate: Fri Apr 26 00:05:07 2024 +0500
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Jun 18 12:53:03 2024 +0200

    Make sure to export autostyles from inside frames anchored to page
    
    These frames need to export content when collecting autostyles, too.
    Regression after commit 69ed893087f89d176a5ec4b263ce8d75774be72b
    (tdf#160253: fix list identifier export decision code, 2024-04-24).
    
    Change-Id: If036cab9327e33d32f494fc765bae8e2d685907c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166650
    Reviewed-by: Caolán McNamara <[email protected]>
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/sw/qa/extras/odfexport/data/table_in_frame_to_page.fodt 
b/sw/qa/extras/odfexport/data/table_in_frame_to_page.fodt
new file mode 100644
index 000000000000..998f7a08e590
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/table_in_frame_to_page.fodt
@@ -0,0 +1,66 @@
+<?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:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph">
+   <style:text-properties fo:font-style="italic"/>
+  </style:style>
+  <style:style style:name="P2" style:family="paragraph">
+   <style:text-properties fo:font-weight="bold"/>
+  </style:style>
+  <style:style style:name="Table1" style:family="table">
+   <style:table-properties style:width="8cm" table:align="margins"/>
+  </style:style>
+  <style:style style:name="Table1.A" style:family="table-column">
+   <style:table-column-properties style:column-width="4cm" 
style:rel-column-width="32767*"/>
+  </style:style>
+  <style:style style:name="Table1.B" style:family="table-column">
+   <style:table-column-properties style:column-width="4cm" 
style:rel-column-width="32768*"/>
+  </style:style>
+  <style:style style:name="Table1.A1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="1mm" fo:border-left="0.5pt solid 
#000000" fo:border-right="none" fo:border-top="0.5pt solid #000000" 
fo:border-bottom="0.5pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table1.B1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="1mm" fo:border="0.5pt solid 
#000000"/>
+  </style:style>
+  <style:style style:name="Table1.A2" style:family="table-cell">
+   <style:table-cell-properties fo:padding="1mm" fo:border-left="0.5pt solid 
#000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.5pt 
solid #000000"/>
+  </style:style>
+  <style:style style:name="Table1.B2" style:family="table-cell">
+   <style:table-cell-properties fo:padding="1mm" fo:border-left="0.5pt solid 
#000000" fo:border-right="0.5pt solid #000000" fo:border-top="none" 
fo:border-bottom="0.5pt solid #000000"/>
+  </style:style>
+  <style:style style:name="fr1" style:family="graphic" 
style:parent-style-name="Frame">
+   <style:graphic-properties style:wrap="parallel" 
style:number-wrapped-paragraphs="no-limit" style:vertical-pos="from-top" 
style:vertical-rel="page" style:horizontal-pos="from-left" 
style:horizontal-rel="page" draw:wrap-influence-on-position="once-concurrent"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <draw:frame draw:style-name="fr1" draw:name="Frame1" 
text:anchor-type="page" text:anchor-page-number="1" svg:x="5cm" svg:y="1cm" 
svg:width="8cm" draw:z-index="0">
+    <draw:text-box fo:min-height="5cm">
+     <table:table table:name="Table1" table:style-name="Table1">
+      <table:table-column table:style-name="Table1.A"/>
+      <table:table-column table:style-name="Table1.B"/>
+      <table:table-row>
+       <table:table-cell table:style-name="Table1.A1" 
office:value-type="string">
+        <text:p text:style-name="P1"/>
+       </table:table-cell>
+       <table:table-cell table:style-name="Table1.B1" 
office:value-type="string">
+        <text:p/>
+       </table:table-cell>
+      </table:table-row>
+      <table:table-row>
+       <table:table-cell table:style-name="Table1.A2" 
office:value-type="string">
+        <text:p/>
+       </table:table-cell>
+       <table:table-cell table:style-name="Table1.B2" 
office:value-type="string">
+        <text:p/>
+       </table:table-cell>
+      </table:table-row>
+     </table:table>
+     <text:p text:style-name="P2"/>
+    </draw:text-box>
+   </draw:frame>
+   <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 e6c3cee113ba..51c77cba4e78 100644
--- a/sw/qa/extras/odfexport/odfexport2.cxx
+++ b/sw/qa/extras/odfexport/odfexport2.cxx
@@ -1478,6 +1478,34 @@ CPPUNIT_TEST_FIXTURE(Test, 
testTdf160253_outline_numbering)
     // assertXPath(pXmlDoc, "//office:body/office:text/text:list"_ostr, 0);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTableInFrameAnchoredToPage)
+{
+    // Given a table in a frame anchored to a page:
+    // it must not assert on export because of missing format for an exported 
table
+    loadAndReload("table_in_frame_to_page.fodt");
+
+    // Check also, that autostyles defined inside that frame are stored 
correctly. If not, then
+    // these paragraphs would refer to styles in <office::styles>, not in 
<office:automatic-styles>,
+    // without the 'italic' and 'bold' attributes.
+    xmlDocUniquePtr pXmlDoc = parseExport("content.xml");
+    OUString P1 = getXPath(
+        pXmlDoc,
+        
"//office:body/office:text/draw:frame/draw:text-box/table:table/table:table-row[1]/"
+        "table:table-cell[1]/text:p"_ostr,
+        "style-name"_ostr);
+    assertXPath(pXmlDoc,
+                "//office:automatic-styles/style:style[@style:name='"_ostr + 
P1.toUtf8()
+                    + "']/style:text-properties",
+                "font-style"_ostr, u"italic"_ustr);
+    OUString P2
+        = getXPath(pXmlDoc, 
"//office:body/office:text/draw:frame/draw:text-box/text:p"_ostr,
+                   "style-name"_ostr);
+    assertXPath(pXmlDoc,
+                "//office:automatic-styles/style:style[@style:name='"_ostr + 
P2.toUtf8()
+                    + "']/style:text-properties",
+                "font-weight"_ostr, u"bold"_ustr);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index c131ffeb1ba1..f9175e03d2c5 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -1634,7 +1634,7 @@ void 
XMLTextParagraphExport::collectTextAutoStylesAndNodeExportOrder(bool bIsPro
         return;
 
     const bool bAutoStyles = true;
-    const bool bExportContent = false;
+    const bool bExportContent = true;
 
     if (auto xTextDocument = GetExport().GetModel().query<XTextDocument>())
     {
commit fc379da9e7bcd1fb26ad290225324b7f341ed980
Author:     Mike Kaganski <[email protected]>
AuthorDate: Wed Apr 24 07:55:35 2024 +0500
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Jun 18 12:53:03 2024 +0200

    tdf#160253: fix list identifier export decision code
    
    Commits 8f48f91009caa86d896f247059874242ed18bf39 (ODT export: omit
    unreferenced <text:list xml:id="...">, 2022-03-10) and
    82bbf63582bdf28e7918e58ebf6657a9144bc9f3  (tdf#155823: Improve the
    check if the list id is not required, 2023-06-14) tried to improve
    deterministic ODF output, by omitting the list identifiers in case
    when those identifiers were unreferenced. The latter of these used
    document model node numbers to check if other lists appeared after
    the last occurrence of the list  that is continuing in the current
    node. But it turned out, that this isn't robust. Consider this ODF:
    
      <text:list xml:id="list1" text:style-name="L1">
       <text:list-item>
        <text:p>a</text:p>
       </text:list-item>
      </text:list>
      <text:p>b<text:note text:id="ftn1" 
text:note-class="endnote"><text:note-citation>i</text:note-citation><text:note-body>
         <text:list text:style-name="L2">
          <text:list-item>
           <text:p>x</text:p>
          </text:list-item>
         </text:list></text:note-body></text:note></text:p>
      <text:list text:continue-list="list1" text:style-name="L1">
       <text:list-item>
        <text:p>c</text:p>
       </text:list-item>
      </text:list>
    
    The paragraphs a, b, and c are all in the main document body,  and
    have sequential document model node numbers  (say, 15, 16, 17). If
    these numbers are checked,  there is no node between node 15 ("a")
    and node 17 ("c") with a different list  (both 15 and 17 belong to
    a list with style "L1" and identifier "list1", and node 16 doesn't
    belong to any lists). That suggests that the list identifier isn't
    needed in this case. Bug when the actual output of node 16 is done,
    it includes a node from an endnote  ("x"),  which is located  in a
    different place in the document model,  and has a node number like
    7 (so not between 15 and 17). The paragraph "x" belongs to another
    list with style  "L2", and is output to ODF between paragraphs "a"
    and "c". Here, we must refer from paragraph "c" to the list of the
    paragraph "a" using the list id, but this is not obvious when only
    considering node numbers,  and requires the prior knowledge of the
    actual order of appearance of lists in the ODF.
    
    Unless we build a DOM,  this is only possible, if we do a two-pass
    output, and collect the nodes order in the first pass.  The output
    already does that in a "collect autostyles" pass. The problem here
    is that the  "collect autostyles"  pass used an optimized function,
    XMLTextParagraphExport::collectTextAutoStylesOptimized, introduced
    in commit  8195d7061ed52ebb98f46d35fe5929762c71e4b3  (INTEGRATION:
    CWS swautomatic01 (1.126.4); FILE MERGED, 2006-12-01) for #i65476#
    and which used style::XAutoStylesSupplier for optimization  to get
    the autostyles.
    
    This drops  XMLTextParagraphExport::collectTextAutoStylesOptimized,
    and reverts to use of  collectTextAutoStyles,  which handles nodes
    in the same order as when writing to ODF. There, we build a vector
    of the node numbers sequence, used later to sort DocumentListNodes.
    
    This uncovered an omission from the work on paragraph mark (commit
    1a88efa8e02a6d765dab13c7110443bb9e6acecf  tdf#155238:  Reimplement
    how ListAutoFormat is stored to ODF, 2023-05-11).  Turns out, that
    the code in SwTextFormatter::NewNumberPortion introduced in commit
    cb0e1b52d68aa6d5b505f91cb4ce577f7f3b2a8f  (sw,  numbering  portion
    format: consider full-para char formats as well,  2022-10-20)  was
    left behind when re-implementing paragraph marks  to use dedicated
    property;  empty trailing spans still affected  how the lists were
    rendered,  and that allowed to overlook import defects,  where the
    paragraph mark properties weren't properly set.
    
    In ODF import (XMLParaContext::endFastElement),  for compatibility,
    this treats empty trailing spans as defining paragraph mark  (when
    the paragraph mark wasn't set explicitly).  This way, the trailing
    spans get converted to the paragraph mark.
    
    In WW8 import,  last cell paragraphs didn't call the code handling
    the paragraph marks. This is also fixed now.
    
    The changes result  in slightly different numbering  of autostyles
    in the ODF.  It seems, that the new numbering more closely follows
    the order of appearance of the autostyles in the output;  and some
    cases of autostyles that were written,  but unreferenced,  are now
    eliminated. The unit tests were updated accordingly.
    
    I hope that the performance impact on the export time would not be
    too large.
    
    It is unclear why outline numbering  exports a list element at all.
    Fixing that to not emit the list element is a separate task / TODO.
    
    Change-Id: I5c99f8d48be77c4454ffac6ffa9f5babfe0d4909
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166572
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/include/xmloff/txtparae.hxx b/include/xmloff/txtparae.hxx
index 436c2d2b629e..ec07d1af8112 100644
--- a/include/xmloff/txtparae.hxx
+++ b/include/xmloff/txtparae.hxx
@@ -114,6 +114,8 @@ class XMLOFF_DLLPUBLIC XMLTextParagraphExport : public 
XMLStyleExport
 
     struct DocumentListNodes;
     std::unique_ptr<DocumentListNodes> mpDocumentListNodes;
+    std::vector<sal_Int32> maDocumentNodeOrder;
+    bool bInDocumentNodeOrderCollection = false;
 
     o3tl::sorted_vector<css::uno::Reference<css::text::XTextFrame>> 
maFrameRecurseGuard;
     o3tl::sorted_vector<css::uno::Reference<css::drawing::XShape>> 
maShapeRecurseGuard;
@@ -472,9 +474,7 @@ public:
         exportText( rText, rBaseSection, true, bIsProgress, 
true/*bExportParagraph*/ );
     }
 
-    // It the model implements the xAutoStylesSupplier interface, the automatic
-    // styles can exported without iterating over the text portions
-    void collectTextAutoStylesOptimized( bool bIsProgress );
+    void collectTextAutoStylesAndNodeExportOrder(bool bIsProgress);
 
     // This method exports all automatic styles that have been collected.
     void exportTextAutoStyles();
@@ -540,6 +540,7 @@ public:
     void PopTextListsHelper();
 
 private:
+    void RecordNodeIndex(const css::uno::Reference<css::text::XTextContent>& 
xTextContent);
     bool ShouldSkipListId(const css::uno::Reference<css::text::XTextContent>& 
xTextContent);
     bool ExportListId() const;
 
diff --git a/sw/qa/extras/htmlexport/xhtmlexport.cxx 
b/sw/qa/extras/htmlexport/xhtmlexport.cxx
index 86026dbd70bd..b1c00a6f81e5 100644
--- a/sw/qa/extras/htmlexport/xhtmlexport.cxx
+++ b/sw/qa/extras/htmlexport/xhtmlexport.cxx
@@ -176,9 +176,9 @@ CPPUNIT_TEST_FIXTURE(XHtmlExportTest, testTdf66305)
     sal_uInt64 nLength = pStream->TellEnd();
     OString aStream(read_uInt8s_ToOString(*pStream, nLength));
     CPPUNIT_ASSERT(
-        aStream.indexOf("<p class=\"paragraph-P6\"><a 
href=\"#__RefHeading__82004_486970805\" "
+        aStream.indexOf("<p class=\"paragraph-P5\"><a 
href=\"#__RefHeading__82004_486970805\" "
                         
"class=\"text-Internet_20_link\">Introduction</a></p><p "
-                        "class=\"paragraph-P7\"> </p>")
+                        "class=\"paragraph-P6\"> </p>")
         != -1);
 }
 
diff --git a/sw/qa/extras/odfexport/data/tdf160253_ordinary_numbering.fodt 
b/sw/qa/extras/odfexport/data/tdf160253_ordinary_numbering.fodt
new file mode 100644
index 000000000000..ca5c1128d1c0
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/tdf160253_ordinary_numbering.fodt
@@ -0,0 +1,43 @@
+<?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:automatic-styles>
+  <text:list-style style:name="L1">
+   <text:list-level-style-number text:level="1" style:num-suffix="." 
style:num-format="1">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="space"/>
+    </style:list-level-properties>
+   </text:list-level-style-number>
+  </text:list-style>
+  <text:list-style style:name="L2">
+   <text:list-level-style-bullet text:level="1" text:bullet-char="•">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="space" 
fo:text-indent="-0.5cm" fo:margin-left="1cm"/>
+    </style:list-level-properties>
+   </text:list-level-style-bullet>
+  </text:list-style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:list xml:id="list1" text:style-name="L1">
+    <text:list-item>
+     <text:p>a</text:p>
+    </text:list-item>
+    <text:list-item>
+     <text:p>b</text:p>
+    </text:list-item>
+   </text:list>
+   <text:p>c<text:note text:id="ftn1" 
text:note-class="endnote"><text:note-citation>i</text:note-citation><text:note-body>
+      <text:list text:style-name="L2">
+       <text:list-item>
+        <text:p>xyz</text:p>
+       </text:list-item>
+      </text:list></text:note-body></text:note></text:p>
+   <text:list text:continue-list="list1" text:style-name="L1">
+    <text:list-item>
+     <text:p>d</text:p>
+    </text:list-item>
+   </text:list>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/odfexport/data/tdf160253_outline_numbering.fodt 
b/sw/qa/extras/odfexport/data/tdf160253_outline_numbering.fodt
new file mode 100644
index 000000000000..2eddd6dd4593
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/tdf160253_outline_numbering.fodt
@@ -0,0 +1,37 @@
+<?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="Heading" style:family="paragraph" 
style:default-outline-level="1" style:list-style-name="Numbering_20_1" 
style:class="text"/>
+  <style:style style:name="Heading_20_1" style:display-name="Heading 1" 
style:family="paragraph" style:parent-style-name="Heading" 
style:next-style-name="Text_20_body" style:default-outline-level="1" 
style:list-style-name="Outline" style:class="text">
+   <style:text-properties fo:font-weight="bold"/>
+  </style:style>
+  <text:outline-style style:name="Outline">
+   <text:outline-level-style text:level="1" style:num-format="1">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="space"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+  </text:outline-style>
+  <text:list-style style:name="Numbering_20_1" style:display-name="Numbering 
1">
+   <text:list-level-style-number text:level="1" style:num-format="1"/>
+  </text:list-style>
+ </office:styles>
+ <office:master-styles>
+  <style:master-page style:name="Standard"/>
+  <style:master-page style:name="Endnote"/>
+ </office:master-styles>
+ <office:automatic-styles>
+  <text:list-style style:name="L1">
+   <text:list-level-style-bullet text:level="1" text:bullet-char="•"/>
+  </text:list-style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:h text:style-name="Heading_20_1" text:outline-level="1">foo</text:h>
+   <text:p>xyz<text:note text:id="ftn1" 
text:note-class="endnote"><text:note-citation>i</text:note-citation><text:note-body>
+    <text:list 
text:style-name="L1"><text:list-item><text:p>abc</text:p></text:list-item></text:list></text:note-body></text:note></text:p>
+   <text:h text:style-name="Heading_20_1" text:outline-level="1">bar</text:h>
+  </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 1a06a8eaf268..e6c3cee113ba 100644
--- a/sw/qa/extras/odfexport/odfexport2.cxx
+++ b/sw/qa/extras/odfexport/odfexport2.cxx
@@ -111,10 +111,14 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf106733)
     CPPUNIT_ASSERT_EQUAL(1, getPages());
     xmlDocUniquePtr pXmlDoc = parseExport("content.xml");
 
+    OUString autostyle = getXPath(pXmlDoc, 
"//office:body/office:text/text:p[2]/text:span"_ostr,
+                                  "style-name"_ostr);
+    OString autostyle_span_xpath = "//style:style[@style:name='" + 
autostyle.toUtf8() + "']";
+
     // keep fo:hyphenate="false" in direct formatting
     assertXPath(
         pXmlDoc,
-        "//style:style[@style:name='T3']/style:text-properties"_ostr,
+        autostyle_span_xpath + "/style:text-properties",
         "hyphenate"_ostr, "false");
 
     // keep fo:hyphenate="false" in character style
@@ -1150,9 +1154,13 @@ 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"_ostr, 
"marker-style-name"_ostr, "T2");
-    assertXPath(pXmlDoc, 
"/office:document-content/office:automatic-styles/style:style[@style:name='T2']/style:text-properties"_ostr,
 "font-size"_ostr, "9pt");
-    assertXPath(pXmlDoc, 
"/office:document-content/office:automatic-styles/style:style[@style:name='T2']/style:text-properties"_ostr,
 "color"_ostr, "#ff0000");
+    OUString autostyle
+        = getXPath(pXmlDoc, "//office:body/office:text/text:p"_ostr, 
"marker-style-name"_ostr);
+    OString style_text_properties
+        = 
"/office:document-content/office:automatic-styles/style:style[@style:name='"
+          + autostyle.toUtf8() + "']/style:text-properties";
+    assertXPath(pXmlDoc, style_text_properties, "font-size"_ostr, "9pt");
+    assertXPath(pXmlDoc, style_text_properties, "color"_ostr, "#ff0000");
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testCommentStyles)
@@ -1430,6 +1438,46 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf160700)
     assertXPath(pXmlDoc, 
"//office:text/text:list/text:list-item/text:p/text:bookmark"_ostr);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf160253_ordinary_numbering)
+{
+    // Given a document with a list, and an out-of-the-list paragraph in the 
middle, having an
+    // endnote, which has a paragraph in another list.
+    // Before the fix, this already failed with
+    //   Error: "list2916587379" is referenced by an IDREF, but not defined.
+    loadAndReload("tdf160253_ordinary_numbering.fodt");
+
+    // Make sure that the fourth paragraph has correct number - it was "1." 
before the fix
+    CPPUNIT_ASSERT_EQUAL(u"3."_ustr,
+                         getProperty<OUString>(getParagraph(4), 
u"ListLabelString"_ustr));
+
+    // Make sure that we emit an identifier for the first list, and refer to 
it in the continuation
+    xmlDocUniquePtr pXmlDoc = parseExport("content.xml");
+    // This failed before the fix, because 'xml:id' attribute wasn't emitted
+    OUString firstListId
+        = getXPath(pXmlDoc, "//office:body/office:text/text:list[1]"_ostr, 
"id"_ostr);
+    CPPUNIT_ASSERT(!firstListId.isEmpty());
+    assertXPath(pXmlDoc, "//office:body/office:text/text:list[2]"_ostr, 
"continue-list"_ostr,
+                firstListId);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf160253_outline_numbering)
+{
+    // Given a document with an outline (chapter) numbering, and a paragraph 
in the middle, having
+    // an endnote, which has a paragraph in a list.
+    // Before the fix, this already failed with
+    //   Error: "list2916587379" is referenced by an IDREF, but not defined.
+    loadAndReload("tdf160253_outline_numbering.fodt");
+
+    // Make sure that the third paragraph has correct number - it was "1" 
before the fix
+    CPPUNIT_ASSERT_EQUAL(u"2"_ustr,
+                         getProperty<OUString>(getParagraph(3), 
u"ListLabelString"_ustr));
+
+    // The difference with the ordinary numbering is that for outline 
numbering, the list element
+    // isn't really necessary. It is a TODO to fix the output, and not export 
the list.
+    // xmlDocUniquePtr pXmlDoc = parseExport("content.xml");
+    // assertXPath(pXmlDoc, "//office:body/office:text/text:list"_ostr, 0);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx
index 84f32e30971f..2d721fd3b112 100644
--- a/sw/source/core/text/txtfld.cxx
+++ b/sw/source/core/text/txtfld.cxx
@@ -657,28 +657,6 @@ SwNumberPortion *SwTextFormatter::NewNumberPortion( 
SwTextFormatInfo &rInf ) con
                     // Build a new numbering font basing on the current 
paragraph font:
                     std::unique_ptr<SwFont> pNumFnt(new SwFont( 
&rInf.GetCharAttr(), pIDSA ));
 
-                    const SwTextNode& rTextNode = 
*rInf.GetTextFrame()->GetTextNodeForParaProps();
-                    if (const SwpHints* pHints = rTextNode.GetpSwpHints())
-                    {
-                        // Also look for an empty character hint that sits at 
the paragraph end:
-                        for (size_t i = 0; i < pHints->Count(); ++i)
-                        {
-                            const SwTextAttr* pHint = 
pHints->GetSortedByEnd(i);
-                            if (pHint->Which() == RES_TXTATR_AUTOFMT && 
pHint->GetEnd()
-                                && pHint->GetStart() == *pHint->GetEnd()
-                                && pHint->GetStart() == 
rTextNode.GetText().getLength())
-                            {
-                                std::shared_ptr<SfxItemSet> pSet
-                                    = pHint->GetAutoFormat().GetStyleHandle();
-                                if (pSet)
-                                {
-                                    pNumFnt->SetDiffFnt(pSet.get(), pIDSA);
-                                    break;
-                                }
-                            }
-                        }
-                    }
-
                     // #i53199#
                     if ( 
!pIDSA->get(DocumentSettingId::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT) )
                     {
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index a2d959d7d3f7..27d6032dd4d2 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -2478,7 +2478,7 @@ void wwSectionManager::SetHdFt(wwSection const &rSection, 
int nSect,
 
 }
 
-void SwWW8ImplReader::AppendTextNode(SwPosition& rPos)
+void SwWW8ImplReader::FinalizeTextNode(SwPosition& rPos, bool bAddNew)
 {
     SwTextNode* pText = m_pPaM->GetPointNode().GetTextNode();
 
@@ -2565,7 +2565,8 @@ void SwWW8ImplReader::AppendTextNode(SwPosition& rPos)
 
     m_bFirstPara = false;
 
-    m_rDoc.getIDocumentContentOperations().AppendTextNode(rPos);
+    if (bAddNew)
+        m_rDoc.getIDocumentContentOperations().AppendTextNode(rPos);
 
     // We can flush all anchored graphics at the end of a paragraph.
     m_xAnchorStck->Flush();
@@ -3481,13 +3482,13 @@ void 
SwWW8ImplReader::simpleAddTextToParagraph(std::u16string_view aAddString)
         else
         {
             m_rDoc.getIDocumentContentOperations().InsertString(*m_pPaM, 
addString.copy(0, nCharsLeft));
-            AppendTextNode(*m_pPaM->GetPoint());
+            FinalizeTextNode(*m_pPaM->GetPoint());
             m_rDoc.getIDocumentContentOperations().InsertString(*m_pPaM, 
addString.copy(nCharsLeft));
         }
     }
     else
     {
-        AppendTextNode(*m_pPaM->GetPoint());
+        FinalizeTextNode(*m_pPaM->GetPoint());
         m_rDoc.getIDocumentContentOperations().InsertString(*m_pPaM, 
addString);
     }
 
@@ -3558,7 +3559,7 @@ bool SwWW8ImplReader::HandlePageBreakChar()
                 && (m_bFirstPara || m_bFirstParaOfPage))
         {
             IsTemp = false;
-            AppendTextNode(*m_pPaM->GetPoint());
+            FinalizeTextNode(*m_pPaM->GetPoint());
             pTemp->SetAttr(*GetDfltAttr(RES_PARATR_NUMRULE));
         }
 
@@ -3637,7 +3638,7 @@ bool SwWW8ImplReader::ReadChar(tools::Long nPosCp, 
tools::Long nCpOfs)
                 // Always insert a txtnode for a column break, e.g. ##
                 SwContentNode *pCntNd=m_pPaM->GetPointContentNode();
                 if (pCntNd!=nullptr && pCntNd->Len()>0) // if par is empty not 
break is needed
-                    AppendTextNode(*m_pPaM->GetPoint());
+                    FinalizeTextNode(*m_pPaM->GetPoint());
                 m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, 
SvxFormatBreakItem(SvxBreak::ColumnBefore, RES_BREAK));
             }
             break;
@@ -4106,7 +4107,7 @@ bool SwWW8ImplReader::ReadText(WW8_CP nStartCp, WW8_CP 
nTextLen, ManTypes nType)
             }
             if (bSplit)
             {
-                AppendTextNode(*m_pPaM->GetPoint());
+                FinalizeTextNode(*m_pPaM->GetPoint());
             }
         }
 
@@ -4221,7 +4222,7 @@ bool SwWW8ImplReader::ReadText(WW8_CP nStartCp, WW8_CP 
nTextLen, ManTypes nType)
                 // to insert a text node.
                 if (!bStartLine && !m_xAnchorStck->empty())
                 {
-                    AppendTextNode(*m_pPaM->GetPoint());
+                    FinalizeTextNode(*m_pPaM->GetPoint());
                 }
                 m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM,
                     SvxFormatBreakItem(SvxBreak::PageBefore, RES_BREAK));
@@ -4234,7 +4235,7 @@ bool SwWW8ImplReader::ReadText(WW8_CP nStartCp, WW8_CP 
nTextLen, ManTypes nType)
     m_xPreviousNode.reset();
 
     if (m_pPaM->GetPoint()->GetContentIndex())
-        AppendTextNode(*m_pPaM->GetPoint());
+        FinalizeTextNode(*m_pPaM->GetPoint());
 
     if (!m_bInHyperlink)
         bJoined = JoinNode(*m_pPaM);
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index f98bcc2ff58e..ca5b34f8e033 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1421,7 +1421,7 @@ private:
 
     bool StyleExists(unsigned int nColl) const { return (nColl < 
m_vColl.size()); }
     SwWW8StyInf *GetStyle(sal_uInt16 nColl) const;
-    void AppendTextNode(SwPosition& rPos);
+    void FinalizeTextNode(SwPosition& rPos, bool bAddNew = true);
 
     void Read_HdFt(int nSect, const SwPageDesc *pPrev,
         const wwSection &rSection);
diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx
index 602256428563..07348ff888d3 100644
--- a/sw/source/filter/ww8/ww8par2.cxx
+++ b/sw/source/filter/ww8/ww8par2.cxx
@@ -2402,7 +2402,7 @@ void WW8TabDesc::CreateSwTable()
     }
 
     if (bInsNode)
-        m_pIo->AppendTextNode(*pPoint);
+        m_pIo->FinalizeTextNode(*pPoint);
 
     m_xTmpPos = m_pIo->m_rDoc.CreateUnoCursor(*m_pIo->m_pPaM->GetPoint());
 
@@ -3497,6 +3497,8 @@ bool SwWW8ImplReader::StartTable(WW8_CP nStartCp)
 
 void SwWW8ImplReader::TabCellEnd()
 {
+    FinalizeTextNode(*m_pPaM->GetPoint(), false);
+
     if (m_nInTable && m_xTableDesc)
         m_xTableDesc->TableCellEnd();
 
diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx
index 6750fa21ae76..975280376800 100644
--- a/sw/source/filter/ww8/ww8par5.cxx
+++ b/sw/source/filter/ww8/ww8par5.cxx
@@ -3478,7 +3478,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, 
OUString& rStr )
     }
 
     if (m_pPaM->GetPoint()->GetContentIndex())
-        AppendTextNode(*m_pPaM->GetPoint());
+        FinalizeTextNode(*m_pPaM->GetPoint());
 
     const SwPosition* pPos = m_pPaM->GetPoint();
 
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index 13270b28c144..b8272f55ccd0 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -881,7 +881,7 @@ void wwSectionManager::CreateSep(const tools::Long nTextPos)
                 if( txtNode->Len() == 0 )
                     insert = false;
         if( insert )
-            mrReader.AppendTextNode(*mrReader.m_pPaM->GetPoint());
+            mrReader.FinalizeTextNode(*mrReader.m_pPaM->GetPoint());
     }
 
     ww::WordVersion eVer = mrReader.GetFib().GetFIBVersion();
@@ -2528,7 +2528,7 @@ bool SwWW8ImplReader::StartApo(const ApoTestResults 
&rApo, const WW8_TablePos *p
                     {
                         // The two fly frames would have the same anchor 
position, leading to
                         // potentially overlapping text, prevent that.
-                        AppendTextNode(*pPoint);
+                        FinalizeTextNode(*pPoint);
                     }
                 }
             }
diff --git a/sw/source/filter/xml/xmlfmte.cxx b/sw/source/filter/xml/xmlfmte.cxx
index 8e20f46e4299..0999076212c1 100644
--- a/sw/source/filter/xml/xmlfmte.cxx
+++ b/sw/source/filter/xml/xmlfmte.cxx
@@ -250,7 +250,7 @@ void SwXMLExport::collectAutoStyles()
                 GetFormExport()->examineForms(xPage);
         }
 
-        GetTextParagraphExport()->collectTextAutoStylesOptimized( 
m_bShowProgress );
+        
GetTextParagraphExport()->collectTextAutoStylesAndNodeExportOrder(m_bShowProgress);
     }
 
     mbAutoStylesCollected = true;
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index f55ee1055825..c131ffeb1ba1 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -39,6 +39,7 @@
 #include <com/sun/star/text/XTextTablesSupplier.hpp>
 #include <com/sun/star/text/XNumberingRulesSupplier.hpp>
 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
 #include <com/sun/star/text/XTextTable.hpp>
 #include <com/sun/star/text/XText.hpp>
 #include <com/sun/star/text/XTextContent.hpp>
@@ -1334,12 +1335,14 @@ struct XMLTextParagraphExport::DocumentListNodes
 {
     struct NodeData
     {
+        std::ptrdiff_t order;
         sal_Int32 index; // see SwNode::GetIndex and SwNodeOffset
         sal_uInt64 style_id; // actually a pointer to NumRule
         OUString list_id;
     };
     std::vector<NodeData> docListNodes;
-    DocumentListNodes(const css::uno::Reference<css::frame::XModel>& xModel)
+    DocumentListNodes(const css::uno::Reference<css::frame::XModel>& xModel,
+                      const std::vector<sal_Int32>& aDocumentNodeOrder)
     {
         // Sequence of nodes, each of them represented by three-element 
sequence,
         // corresponding to NodeData members
@@ -1361,12 +1364,18 @@ struct XMLTextParagraphExport::DocumentListNodes
         for (const auto& node : nodes)
         {
             assert(node.getLength() == 3);
-            docListNodes.push_back({ node[0].get<sal_Int32>(), 
node[1].get<sal_uInt64>(),
-                                     node[2].get<OUString>() });
+            sal_Int32 nodeIndex = node[0].get<sal_Int32>();
+            auto nodeOrder = std::distance(
+                aDocumentNodeOrder.begin(),
+                std::find(aDocumentNodeOrder.begin(), 
aDocumentNodeOrder.end(), nodeIndex));
+            docListNodes.push_back({ .order = nodeOrder,
+                                     .index = nodeIndex,
+                                     .style_id = node[1].get<sal_uInt64>(),
+                                     .list_id = node[2].get<OUString>() });
         }
 
         std::sort(docListNodes.begin(), docListNodes.end(),
-                  [](const NodeData& lhs, const NodeData& rhs) { return 
lhs.index < rhs.index; });
+                  [](const NodeData& lhs, const NodeData& rhs) { return 
lhs.order < rhs.order; });
     }
     bool ShouldSkipListId(const Reference<XTextContent>& xTextContent) const
     {
@@ -1387,10 +1396,9 @@ struct XMLTextParagraphExport::DocumentListNodes
                 return false;
             }
 
-            auto it = std::lower_bound(docListNodes.begin(), 
docListNodes.end(), index,
-                                       [](const NodeData& lhs, sal_Int32 rhs)
-                                       { return lhs.index < rhs; });
-            if (it == docListNodes.end() || it->index != index)
+            auto it = std::find_if(docListNodes.begin(), docListNodes.end(),
+                                   [index](const NodeData& el) { return 
el.index == index; });
+            if (it == docListNodes.end())
                 return false;
 
             // We need to write the id, when there will be continuation of the 
list either with
@@ -1618,9 +1626,7 @@ const enum XMLTokenEnum lcl_XmlReferenceElements[] = {
 const enum XMLTokenEnum lcl_XmlBookmarkElements[] = {
     XML_BOOKMARK, XML_BOOKMARK_START, XML_BOOKMARK_END };
 
-// This function replaces the text portion iteration during auto style
-// collection.
-void XMLTextParagraphExport::collectTextAutoStylesOptimized( bool bIsProgress )
+void XMLTextParagraphExport::collectTextAutoStylesAndNodeExportOrder(bool 
bIsProgress)
 {
     GetExport().GetShapeExport(); // make sure the graphics styles family is 
added
 
@@ -1630,60 +1636,11 @@ void 
XMLTextParagraphExport::collectTextAutoStylesOptimized( bool bIsProgress )
     const bool bAutoStyles = true;
     const bool bExportContent = false;
 
-    // Export AutoStyles:
-    Reference< XAutoStylesSupplier > xAutoStylesSupp( GetExport().GetModel(), 
UNO_QUERY );
-    if ( xAutoStylesSupp.is() )
+    if (auto xTextDocument = GetExport().GetModel().query<XTextDocument>())
     {
-        Reference< XAutoStyles > xAutoStyleFamilies = 
xAutoStylesSupp->getAutoStyles();
-        const auto collectFamily = [this, &xAutoStyleFamilies](const OUString& 
sName,
-                                                               XmlStyleFamily 
nFamily) {
-            Any aAny = xAutoStyleFamilies->getByName( sName );
-            Reference< XAutoStyleFamily > xAutoStyles = 
*o3tl::doAccess<Reference<XAutoStyleFamily>>(aAny);
-            Reference < XEnumeration > xAutoStylesEnum( 
xAutoStyles->createEnumeration() );
-
-            while ( xAutoStylesEnum->hasMoreElements() )
-            {
-                aAny = xAutoStylesEnum->nextElement();
-                Reference< XAutoStyle > xAutoStyle = 
*o3tl::doAccess<Reference<XAutoStyle>>(aAny);
-                Reference < XPropertySet > xPSet( xAutoStyle, uno::UNO_QUERY );
-                Add( nFamily, xPSet, {}, true );
-            }
-        };
-        collectFamily("CharacterStyles", XmlStyleFamily::TEXT_TEXT);
-        collectFamily("RubyStyles", XmlStyleFamily::TEXT_RUBY);
-        collectFamily("ParagraphStyles", XmlStyleFamily::TEXT_PARAGRAPH);
-    }
-
-    // Export Field AutoStyles:
-    Reference< XTextFieldsSupplier > xTextFieldsSupp( GetExport().GetModel(), 
UNO_QUERY );
-    if ( xTextFieldsSupp.is() )
-    {
-        Reference< XEnumerationAccess > xTextFields = 
xTextFieldsSupp->getTextFields();
-        Reference < XEnumeration > xTextFieldsEnum( 
xTextFields->createEnumeration() );
-
-        while ( xTextFieldsEnum->hasMoreElements() )
-        {
-            Any aAny = xTextFieldsEnum->nextElement();
-            Reference< XTextField > xTextField = 
*o3tl::doAccess<Reference<XTextField>>(aAny);
-            exportTextField( xTextField, bAutoStyles, bIsProgress,
-                !xAutoStylesSupp.is(), nullptr );
-            try
-            {
-                Reference < XPropertySet > xSet( xTextField, UNO_QUERY );
-                Reference < XText > xText;
-                Any a = xSet->getPropertyValue("TextRange");
-                a >>= xText;
-                if ( xText.is() )
-                {
-                    exportText( xText, true, bIsProgress, bExportContent );
-                    GetExport().GetTextParagraphExport()
-                        ->collectTextAutoStyles( xText );
-                }
-            }
-            catch (Exception&)
-            {
-            }
-        }
+        bInDocumentNodeOrderCollection = true;
+        collectTextAutoStyles(xTextDocument->getText(), bIsProgress);
+        bInDocumentNodeOrderCollection = false;
     }
 
     // Export text frames:
@@ -1730,47 +1687,11 @@ void 
XMLTextParagraphExport::collectTextAutoStylesOptimized( bool bIsProgress )
             }
         }
 
-    sal_Int32 nCount;
-    // AutoStyles for sections
-    Reference< XTextSectionsSupplier > xSectionsSupp( GetExport().GetModel(), 
UNO_QUERY );
-    if ( xSectionsSupp.is() )
-    {
-        Reference< XIndexAccess > xSections( xSectionsSupp->getTextSections(), 
UNO_QUERY );
-        if ( xSections.is() )
-        {
-            nCount = xSections->getCount();
-            for( sal_Int32 i = 0; i < nCount; ++i )
-            {
-                Any aAny = xSections->getByIndex( i );
-                Reference< XTextSection > xSection = 
*o3tl::doAccess<Reference<XTextSection>>(aAny);
-                Reference < XPropertySet > xPSet( xSection, uno::UNO_QUERY );
-                Add( XmlStyleFamily::TEXT_SECTION, xPSet );
-            }
-        }
-    }
-
-    // AutoStyles for tables (Note: suppress autostyle collection for 
paragraphs in exportTable)
-    Reference< XTextTablesSupplier > xTablesSupp( GetExport().GetModel(), 
UNO_QUERY );
-    if ( xTablesSupp.is() )
-    {
-        Reference< XIndexAccess > xTables( xTablesSupp->getTextTables(), 
UNO_QUERY );
-        if ( xTables.is() )
-        {
-            nCount = xTables->getCount();
-            for( sal_Int32 i = 0; i < nCount; ++i )
-            {
-                Any aAny = xTables->getByIndex( i );
-                Reference< XTextTable > xTable = 
*o3tl::doAccess<Reference<XTextTable>>(aAny);
-                exportTable( xTable, true, true );
-            }
-        }
-    }
-
     Reference< XNumberingRulesSupplier > xNumberingRulesSupp( 
GetExport().GetModel(), UNO_QUERY );
     if ( xNumberingRulesSupp.is() )
     {
         Reference< XIndexAccess > xNumberingRules = 
xNumberingRulesSupp->getNumberingRules();
-        nCount = xNumberingRules->getCount();
+        sal_Int32 nCount = xNumberingRules->getCount();
         // Custom outline assignment lost after re-importing sxw (#i73361#)
         for( sal_Int32 i = 0; i < nCount; ++i )
         {
@@ -1896,14 +1817,36 @@ bool XMLTextParagraphExport::ExportListId() const
            && GetExport().getSaneDefaultVersion() >= 
SvtSaveOptions::ODFSVER_012;
 }
 
+void XMLTextParagraphExport::RecordNodeIndex(const 
css::uno::Reference<css::text::XTextContent>& xTextContent)
+{
+    if (!bInDocumentNodeOrderCollection)
+        return;
+    if (auto xPropSet = xTextContent.query<css::beans::XPropertySet>())
+    {
+        try
+        {
+            sal_Int32 index = 0;
+            // See SwXParagraph::Impl::GetPropertyValues_Impl
+            xPropSet->getPropertyValue("ODFExport_NodeIndex") >>= index;
+            assert(std::find(maDocumentNodeOrder.begin(), 
maDocumentNodeOrder.end(), index)
+                   == maDocumentNodeOrder.end());
+            maDocumentNodeOrder.push_back(index);
+        }
+        catch (css::beans::UnknownPropertyException&)
+        {
+            // That's absolutely fine!
+        }
+    }
+}
+
 bool XMLTextParagraphExport::ShouldSkipListId(const Reference<XTextContent>& 
xTextContent)
 {
     if (!mpDocumentListNodes)
     {
         if (ExportListId())
-            mpDocumentListNodes.reset(new 
DocumentListNodes(GetExport().GetModel()));
+            mpDocumentListNodes.reset(new 
DocumentListNodes(GetExport().GetModel(), maDocumentNodeOrder));
         else
-            mpDocumentListNodes.reset(new DocumentListNodes({}));
+            mpDocumentListNodes.reset(new DocumentListNodes({}, {}));
     }
 
     return mpDocumentListNodes->ShouldSkipListId(xTextContent);
@@ -1954,6 +1897,7 @@ void XMLTextParagraphExport::exportTextContentEnumeration(
         {
             if( bAutoStyles )
             {
+                RecordNodeIndex(xTxtCntnt);
                 exportListAndSectionChange( xCurrentTextSection, xTxtCntnt,
                                             aPrevNumInfo, aNextNumInfo,
                                             bAutoStyles );
@@ -2325,7 +2269,6 @@ void XMLTextParagraphExport::exportParagraph(
 
     Reference < XEnumerationAccess > xEA( rTextContent, UNO_QUERY );
     Reference < XEnumeration > xTextEnum = xEA->createEnumeration();
-    const bool bHasPortions = xTextEnum.is();
 
     Reference < XEnumeration> xContentEnum;
     Reference < XContentEnumerationAccess > xCEA( rTextContent, UNO_QUERY );
@@ -2359,22 +2302,10 @@ void XMLTextParagraphExport::exportParagraph(
 
     bool bPrevCharIsSpace(true); // true because whitespace at start is ignored
 
-    if( bAutoStyles )
-    {
-        if( bHasContentEnum )
-            exportTextContentEnumeration(
-                                    xContentEnum, bAutoStyles, xSection,
-                                    bIsProgress );
-        if ( bHasPortions )
-        {
-            exportTextRangeEnumeration(xTextEnum, bAutoStyles, bIsProgress, 
bPrevCharIsSpace);
-        }
-    }
-    else
     {
         enum XMLTokenEnum eElem =
             0 < nOutlineLevel ? XML_H : XML_P;
-        SvXMLElementExport aElem( GetExport(), eExtensionNS == 
TextPNS::EXTENSION ? XML_NAMESPACE_LO_EXT : XML_NAMESPACE_TEXT, eElem,
+        SvXMLElementExport aElem( GetExport(), !bAutoStyles, eExtensionNS == 
TextPNS::EXTENSION ? XML_NAMESPACE_LO_EXT : XML_NAMESPACE_TEXT, eElem,
                                   true, false );
         if( bHasContentEnum )
         {
diff --git a/xmloff/source/text/txtparai.cxx b/xmloff/source/text/txtparai.cxx
index c777fa0c2929..b46cdafb49f9 100644
--- a/xmloff/source/text/txtparai.cxx
+++ b/xmloff/source/text/txtparai.cxx
@@ -1792,6 +1792,46 @@ void XMLParaContext::endFastElement(sal_Int32 )
                                                true,
                                                mbOutlineContentVisible);
 
+    bool bEmptyHints = false;
+    XMLHint_Impl* pMarkerStyleHint = nullptr;
+    if (m_xHints)
+    {
+        uno::Reference<text::XTextRangeCompare> 
xCompare(xTxtImport->GetText(), uno::UNO_QUERY);
+        if (xCompare.is())
+        {
+            try
+            {
+                for (const auto& pHint : m_xHints->GetHints())
+                {
+                    if (xCompare->compareRegionStarts(pHint->GetStart(), 
pHint->GetEnd()) == 0)
+                    {
+                        bEmptyHints = true;
+
+                        // Is this the trailing empty span, defining the 
paragraph mark properties?
+                        // Convert it to the marker style, for backward 
compatibility with documents
+                        // created between commits 
6249858a8972aef077e0249bd93cfe8f01bce4d6 and
+                        // 1a88efa8e02a6d765dab13c7110443bb9e6acecf, where the 
trailing empty spans
+                        // were used to store the marker formatting
+                        if (!m_aMarkerStyleName.hasValue()
+                            && 
xCompare->compareRegionStarts(pHint->GetStart(), xEnd) == 0)
+                        {
+                            if (auto pStyle = 
GetImport().GetTextImport()->FindAutoCharStyle(
+                                    
static_cast<XMLStyleHint_Impl*>(pHint.get())->GetStyleName()))
+                            {
+                                m_aMarkerStyleName = pStyle->GetAutoName();
+                                pMarkerStyleHint = pHint.get();
+                            }
+                        }
+                    }
+                }
+            }
+            catch (const uno::Exception&)
+            {
+                TOOLS_WARN_EXCEPTION("xmloff.text", "");
+            }
+        }
+    }
+
     if (m_aMarkerStyleName.hasValue())
     {
         if (auto xPropSet = xStart.query<css::beans::XPropertySet>())
@@ -1853,26 +1893,7 @@ void XMLParaContext::endFastElement(sal_Int32 )
     {
         bool bSetNoFormatAttr = false;
         uno::Reference<beans::XPropertySet> xCursorProps(xAttrCursor, 
uno::UNO_QUERY);
-        int nEmptyHints = 0;
-        uno::Reference<text::XTextRangeCompare> 
xCompare(xTxtImport->GetText(), uno::UNO_QUERY);
-        if (xCompare.is())
-        {
-            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())
+        if (bEmptyHints || 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.
@@ -1891,6 +1912,7 @@ void XMLParaContext::endFastElement(sal_Int32 )
             switch( pHint->GetType() )
             {
             case XMLHintType::XML_HINT_STYLE:
+                if (pHint != pMarkerStyleHint) // already processed above
                 {
                     const OUString& rStyleName =
                             static_cast<XMLStyleHint_Impl 
*>(pHint)->GetStyleName();
commit d9f0dab6a3e24731057f0edb9f074cb511a897a2
Author:     Oliver Specht <[email protected]>
AuthorDate: Tue Jun 11 08:51:09 2024 +0200
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Jun 18 12:53:03 2024 +0200

    tdf#161521 fix page margins on first page with mirrord layout
    
    Documents starting with an even page on a mirrored layout need
    to switch left/right margin on the first page.
    Applies also to docx export.
    JUnit test included
    
    Change-Id: Ia363941c6a7a25f9208acc7e40b77baa88080780
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168658
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <[email protected]>
    Tested-by: Gabor Kelemen <[email protected]>

diff --git a/sw/qa/extras/ooxmlexport/data/A019_min.docx 
b/sw/qa/extras/ooxmlexport/data/A019_min.docx
new file mode 100755
index 000000000000..c7c0c890accf
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/A019_min.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx
index d6193305e96c..793ee8171a1a 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx
@@ -1220,6 +1220,23 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf148952_2010)
     CPPUNIT_ASSERT_EQUAL(OUString("Black"), title);
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf153196, "A019_min.docx")
+{
+    uno::Reference<beans::XPropertySet> xPageStyle;
+    getStyles("PageStyles")->getByName("Converted1") >>= xPageStyle;
+    sal_Int32 nLeftMargin{};
+    xPageStyle->getPropertyValue("LeftMargin") >>= nLeftMargin;
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 4265
+    // - Actual  : 0
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4265), nLeftMargin);
+    sal_Int32 nRightMargin{};
+    xPageStyle->getPropertyValue("RightMargin") >>= nRightMargin;
+    // - Expected: 0
+    // - Actual  : 4265
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nRightMargin);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 28da6d28838d..16beec947965 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -9238,6 +9238,17 @@ void DocxAttributeOutput::FormatLRSpace( const 
SvxLRSpaceItem& rLRSpace )
 
         m_pageMargins.nLeft += 
sal::static_int_cast<sal_uInt16>(rLRSpace.GetLeft());
         m_pageMargins.nRight += 
sal::static_int_cast<sal_uInt16>(rLRSpace.GetRight());
+        // if page layout is 'left' then left/right margin need to be exchanged
+        // as it is exported as mirrored layout starting with even page
+        const WW8_SepInfo *pSectionInfo = 
m_rExport.Sections().CurrentSectionInfo();
+        if (pSectionInfo->pPageDesc &&
+            m_rExport.isMirroredMargin() &&
+            ((pSectionInfo->pPageDesc->ReadUseOn() & UseOnPage::All) == 
UseOnPage::Left))
+        {
+            sal_uInt16 nLeft = m_pageMargins.nLeft;
+            m_pageMargins.nLeft = m_pageMargins.nRight;
+            m_pageMargins.nRight = nLeft;
+        }
         sal_uInt16 nGutter = rLRSpace.GetGutterMargin();
 
         AddToAttrList( m_pSectionSpacingAttrList,
diff --git a/sw/source/filter/ww8/docxexport.hxx 
b/sw/source/filter/ww8/docxexport.hxx
index 95da64d24408..7f4ab826c40d 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -282,9 +282,6 @@ private:
     /// Writes word/vbaProject.bin.
     void WriteVBA();
 
-    /// return true if Page Layout is set as Mirrored
-    bool isMirroredMargin();
-
 public:
     /// All xml namespaces to be used at the top of any text .xml file (main 
doc, headers, footers,...)
     rtl::Reference<sax_fastparser::FastAttributeList> MainXmlNamespaces();
@@ -322,6 +319,9 @@ public:
     // needed in docxsdrexport.cxx and docxattributeoutput.cxx
     sal_Int32 getWordCompatibilityModeFromGrabBag() const;
 
+    /// return true if Page Layout is set as Mirrored
+    bool isMirroredMargin();
+
 private:
     DocxExport( const DocxExport& ) = delete;
 
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx 
b/writerfilter/source/dmapper/PropertyMap.cxx
index af07ba1cdd9e..3193e7a1fba1 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -1433,14 +1433,23 @@ void 
SectionPropertyMap::CreateEvenOddPageStyleCopy(DomainMapper_Impl& rDM_Impl,
         "HeaderText", "HeaderTextLeft", "HeaderTextFirst",
         "FooterText", "FooterTextLeft", "FooterTextFirst" };
 
+    bool isMirrorMargins = PageBreakType::Even == eBreakType && 
rDM_Impl.GetSettingsTable()->GetMirrorMarginSettings();
     for (const auto& rProperty : propertyList)
     {
         if ((rProperty.Attributes & beans::PropertyAttribute::READONLY) == 0)
         {
             if (staticDenylist.find(rProperty.Name) == staticDenylist.end())
             {
+                OUString sSetName = rProperty.Name;
+                if (isMirrorMargins)
+                {
+                    if (rProperty.Name == u"LeftMargin"_ustr)
+                        sSetName = u"RightMargin"_ustr;
+                    else if (rProperty.Name == u"RightMargin"_ustr)
+                        sSetName = u"LeftMargin"_ustr;
+                }
                 evenOddStyle->setPropertyValue(
-                    rProperty.Name,
+                    sSetName,
                     pageProperties->getPropertyValue(rProperty.Name));
             }
         }
commit 04928d62b0dbdf6debbb92722264651182aba167
Author:     Oliver Specht <[email protected]>
AuthorDate: Wed May 22 16:30:21 2024 +0200
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Jun 18 12:53:03 2024 +0200

    tdf#159695 Disable Data Validation in protected sheets
    
    While the menu entry Data/Validity was disabled the context
    menu entry Data Validation was still enabled. This is fixed now.
    
    Change-Id: Ifa183f79ed85e5c46e73b4fa3e282c48e9de6c89
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167964
    Reviewed-by: Balazs Varga <[email protected]>
    Tested-by: Jenkins
    Tested-by: Gabor Kelemen <[email protected]>

diff --git a/sc/sdi/cellsh.sdi b/sc/sdi/cellsh.sdi
index 84217c63c949..a66b8b965c26 100644
--- a/sc/sdi/cellsh.sdi
+++ b/sc/sdi/cellsh.sdi
@@ -61,7 +61,7 @@ interface CellSelection
     SID_SUBTOTALS           [ ExecMethod = ExecuteDB; StateMethod = 
GetDBState; ]
     SID_PIVOT_TABLE         [ ExecMethod = ExecuteDB; StateMethod = 
GetDBState; ]
     FID_VALIDATION          [ ExecMethod = ExecuteDB; StateMethod = 
GetBlockState; ]
-    FID_CURRENTVALIDATION   [ ExecMethod = ExecuteDB; StateMethod = GetState; ]
+    FID_CURRENTVALIDATION   [ ExecMethod = ExecuteDB; StateMethod = 
GetBlockState; ]
     SID_TEXT_TO_COLUMNS     [ ExecMethod = ExecuteDB; StateMethod = 
GetDBState; ]
 
     // } database operations
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
index 1a866df3c881..daf68eba0b1d 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -317,6 +317,7 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet )
                     bNeedEdit = false;
                 break;
 
+            case FID_CURRENTVALIDATION:
             case FID_VALIDATION:
                 {
                     if ( pDocShell && pDocShell->IsDocShared() )

Reply via email to