sw/qa/extras/ooxmlexport/data/tdf148455_1.docx    |binary
 sw/qa/extras/ooxmlexport/data/tdf148455_2.docx    |binary
 sw/qa/extras/ooxmlexport/ooxmlexport17.cxx        |   24 ++++++++++++++++++++++
 sw/source/filter/ww8/docxattributeoutput.cxx      |    9 ++++++++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx |   10 +++++++--
 5 files changed, 41 insertions(+), 2 deletions(-)

New commits:
commit 270e8967a720166205263cf695aedb00f8f7ecd9
Author:     Vasily Melenchuk <vasily.melenc...@cib.de>
AuthorDate: Mon May 16 21:21:51 2022 +0300
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed May 18 16:46:56 2022 +0200

    tdf#148455 docx import/export: improvements to lvlOverride
    
    On save LO was just emitting w:lvlOverride to actual level
    where override does happen. But MS Word won't accept override
    for next level if there are no overrides for previous ones.
    
    For example, if we are overriding level 3 we should also emit
    empty lvlOverride for levels 0-2.
    
    Provided fix did cause some problems on DOCX import: overrides
    were applied to current level, but in this context current !=
    actual level where override did happen.
    
    Change-Id: Ia00dd9a5990f7f122027e8126f411642c32da189
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134411
    Tested-by: Jenkins
    Tested-by: Gabor Kelemen <kelem...@ubuntu.com>
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>
    (cherry picked from commit 198381eb32edcc3e82d0f23df65f0804a08b44e6)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134452
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf148455_1.docx 
b/sw/qa/extras/ooxmlexport/data/tdf148455_1.docx
new file mode 100644
index 000000000000..295d3ee744c7
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf148455_1.docx 
differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf148455_2.docx 
b/sw/qa/extras/ooxmlexport/data/tdf148455_2.docx
new file mode 100644
index 000000000000..3cde58ce5a77
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf148455_2.docx 
differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index 41c188a3532e..9e17190c0260 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -321,6 +321,30 @@ DECLARE_OOXMLEXPORT_TEST(testTdf144668, "tdf144668.odt")
     CPPUNIT_ASSERT_EQUAL(OUString("[001]"), getProperty<OUString>(xPara2, 
"ListLabelString"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf148455_1, "tdf148455_1.docx")
+{
+    uno::Reference<beans::XPropertySet> xPara2(getParagraph(3, u"1.1.1"), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("1.1.1."), getProperty<OUString>(xPara2, 
"ListLabelString"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf148455_2, "tdf148455_2.docx")
+{
+    xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+    if (!pXmlDoc)
+       return; // initial import, no further checks
+
+    // Find list id for restarted list
+    sal_Int32 nListId = getXPath(pXmlDoc, 
"/w:document/w:body/w:p[3]/w:pPr/w:numPr/w:numId", "val").toInt32();
+
+    xmlDocUniquePtr pNumberingDoc = parseExport("word/numbering.xml");
+
+    // Ensure we have empty lvlOverride for levels 0 - 1
+    getXPath(pNumberingDoc, "/w:numbering/w:num[@w:numId='" + 
OString::number(nListId) +"']/w:lvlOverride[@w:ilvl='0']", "");
+    getXPath(pNumberingDoc, "/w:numbering/w:num[@w:numId='" + 
OString::number(nListId) +"']/w:lvlOverride[@w:ilvl='1']", "");
+    // And normal overrride for level 2
+    getXPath(pNumberingDoc, "/w:numbering/w:num[@w:numId='" + 
OString::number(nListId) +"']/w:lvlOverride[@w:ilvl='2']/w:startOverride", 
"val");
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testTdf147978enhancedPathABVW)
 {
     load(DATA_DIRECTORY, "tdf147978_enhancedPath_commandABVW.odt");
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 7bddf3121813..6f8a24acd255 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -7715,6 +7715,7 @@ void DocxAttributeOutput::OverrideNumberingDefinition(
     SwNumRule const& rAbstractRule = 
*(*m_rExport.m_pUsedNumTable)[nAbstractNum - 1];
     sal_uInt8 const nLevels = static_cast<sal_uInt8>(rRule.IsContinusNum()
         ? WW8ListManager::nMinLevel : WW8ListManager::nMaxLevel);
+    sal_uInt8 nPreviousOverrideLevel = 0;
     for (sal_uInt8 nLevel = 0; nLevel < nLevels; ++nLevel)
     {
         const auto levelOverride = rLevelOverrides.find(nLevel);
@@ -7724,6 +7725,14 @@ void DocxAttributeOutput::OverrideNumberingDefinition(
         // or we have a level numbering override
         if (bListsAreDifferent || levelOverride != rLevelOverrides.end())
         {
+            // If there are "gaps" in w:lvlOverride numbers, MS Word can have 
issues with numbering.
+            // So we need to emit empty override tokens up to current one.
+            while (nPreviousOverrideLevel < nLevel)
+            {
+                m_pSerializer->singleElementNS(XML_w, XML_lvlOverride, 
FSNS(XML_w, XML_ilvl), OString::number(nPreviousOverrideLevel));
+                nPreviousOverrideLevel++;
+            }
+
             m_pSerializer->startElementNS(XML_w, XML_lvlOverride, FSNS(XML_w, 
XML_ilvl), OString::number(nLevel));
 
             if (bListsAreDifferent)
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 8cd6f94e5b4c..de95db45391a 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -2169,9 +2169,15 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
                                     }
                                 }
                             }
-                            if (pList->GetCurrentLevel())
+
+                            sal_Int16 nCurrentLevel = GetListLevel(pEntry, 
pPropertyMap);
+                            if (nCurrentLevel == -1)
+                                nCurrentLevel = 0;
+
+                            const ListLevel::Pointer pListLevel = 
pList->GetLevel(nCurrentLevel);
+                            if (pListLevel)
                             {
-                                sal_Int16 nOverrideLevel = 
pList->GetCurrentLevel()->GetStartOverride();
+                                sal_Int16 nOverrideLevel = 
pListLevel->GetStartOverride();
                                 if (nOverrideLevel != -1 && 
m_aListOverrideApplied.find(nListId) == m_aListOverrideApplied.end())
                                 {
                                     // Apply override: we have override 
instruction for this level

Reply via email to