sw/qa/extras/ooxmlexport/data/tdf104348_contextMargin.docx       |binary
 sw/qa/extras/ooxmlexport/data/tdf104354-2.docx                   |binary
 sw/qa/extras/ooxmlexport/data/tdf106062_nonHangingFootnote.odt   |binary
 sw/qa/extras/ooxmlexport/data/tdf117504_numberingIndent.docx     |binary
 sw/qa/extras/ooxmlexport/data/tdf118521_marginsLR.docx           |binary
 sw/qa/extras/ooxmlexport/data/tdf119188_list_margin_in_cell.docx |binary
 sw/qa/extras/ooxmlexport/data/tdf126723.docx                     |binary
 sw/qa/extras/ooxmlexport/data/tdf95377.docx                      |binary
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx                         |    3 
 sw/qa/extras/ooxmlexport/ooxmlexport10.cxx                       |   31 
 sw/qa/extras/ooxmlexport/ooxmlexport11.cxx                       |   59 +
 sw/qa/extras/ooxmlexport/ooxmlexport9.cxx                        |   52 +
 sw/qa/extras/uiwriter/data2/tdf90069.docx                        |binary
 sw/qa/extras/uiwriter/uiwriter2.cxx                              |   33 +
 sw/source/filter/ww8/wrtw8nds.cxx                                |   13 
 writerfilter/source/dmapper/DomainMapper.cxx                     |  138 ----
 writerfilter/source/dmapper/DomainMapper_Impl.cxx                |  315 
+++++++++-
 writerfilter/source/dmapper/DomainMapper_Impl.hxx                |   17 
 writerfilter/source/dmapper/NumberingManager.cxx                 |    1 
 writerfilter/source/dmapper/StyleSheetTable.cxx                  |    3 
 writerfilter/source/dmapper/StyleSheetTable.hxx                  |    1 
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx            |    3 
 22 files changed, 514 insertions(+), 155 deletions(-)

New commits:
commit f30585abfe198914511df004ac712f0e066cf0b9
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Wed Jan 8 14:26:40 2020 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:50 2020 +0200

    tdf#90069 DOCX: fix character style of new table rows
    
    DOCX table import didn't set paragraph level
    character styles on paragraph level, only on
    text portions, resulting default character style
    in the newly inserted table rows instead of copying
    the style of the previous table row.
    
    (cherry picked from commit 2ab481b038b62b1ff576ac4d49d03c1798cd7f84)
    
    Conflicts:
            sw/qa/extras/uiwriter/uiwriter2.cxx
    
    Change-Id: Idb4438c767bdc7e0026fc6e0f0a795d8efdda3c8

diff --git a/sw/qa/extras/uiwriter/data2/tdf90069.docx 
b/sw/qa/extras/uiwriter/data2/tdf90069.docx
new file mode 100644
index 000000000000..719502a67e78
Binary files /dev/null and b/sw/qa/extras/uiwriter/data2/tdf90069.docx differ
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx 
b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 2da2640e7fcc..374c8c6b2b37 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -24,6 +24,8 @@
 #include <xmloff/odffields.hxx>
 #include <com/sun/star/frame/DispatchHelper.hpp>
 #include <fmtornt.hxx>
+#include <editeng/fontitem.hxx>
+#include <ndtxt.hxx>
 
 namespace
 {
@@ -45,6 +47,7 @@ public:
     void testDropDownFormFieldInsertion();
     void testMixedFormFieldInsertion();
     void testTdf122942();
+    void testTdf90069();
 
     CPPUNIT_TEST_SUITE(SwUiWriterTest2);
     CPPUNIT_TEST(testTdf101534);
@@ -57,6 +60,7 @@ public:
     CPPUNIT_TEST(testDropDownFormFieldInsertion);
     CPPUNIT_TEST(testMixedFormFieldInsertion);
     CPPUNIT_TEST(testTdf122942);
+    CPPUNIT_TEST(testTdf90069);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -475,6 +479,35 @@ void SwUiWriterTest2::testTdf122942()
 #endif
 }
 
+void SwUiWriterTest2::testTdf90069()
+{
+    SwDoc* pDoc = createDoc("tdf90069.docx");
+
+    SwXTextDocument* pTextDoc = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+
+    SwDocShell* pDocShell = pTextDoc->GetDocShell();
+    CPPUNIT_ASSERT(pDocShell);
+
+    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+    CPPUNIT_ASSERT(pWrtShell);
+
+    sal_uLong nIndex = pWrtShell->GetCursor()->GetNode().GetIndex();
+
+    lcl_dispatchCommand(mxComponent, ".uno:InsertRowsAfter", {});
+    pWrtShell->Down(false);
+    pWrtShell->Insert("foo");
+
+    SwTextNode* pTextNodeA1 = 
static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex]);
+    CPPUNIT_ASSERT(pTextNodeA1->GetText().startsWith("Insert"));
+    nIndex = pWrtShell->GetCursor()->GetNode().GetIndex();
+    SwTextNode* pTextNodeA2 = 
static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex]);
+    CPPUNIT_ASSERT_EQUAL(OUString("foo"), pTextNodeA2->GetText());
+    CPPUNIT_ASSERT_EQUAL(true, 
pTextNodeA2->GetSwAttrSet().HasItem(RES_CHRATR_FONT));
+    OUString sFontName = 
pTextNodeA2->GetSwAttrSet().GetItem(RES_CHRATR_FONT)->GetFamilyName();
+    CPPUNIT_ASSERT_EQUAL(OUString("Lohit Devanagari"), sFontName);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest2);
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 0838e1713967..a6f62a7b4f23 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1477,6 +1477,19 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
                         }
                     }
                 }
+
+                // tdf#90069 in tables, apply paragraph level character style 
also on
+                // paragraph level to support its copy during insertion of new 
table rows
+                if ( xParaProps && m_nTableDepth > 0 )
+                {
+                    uno::Sequence< beans::PropertyValue > aValues = 
pParaContext->GetPropertyValues(false);
+
+                    for( const auto& rProp : aValues )
+                    {
+                        if ( rProp.Name.startsWith("Char") && rProp.Name != 
"CharStyleName" && rProp.Name != "CharInteropGrabBag" )
+                            xParaProps->setPropertyValue( rProp.Name, 
rProp.Value );
+                    }
+                }
             }
             if( !bKeepLastParagraphProperties )
                 rAppendContext.pLastParagraphProperties = pToBeSavedProperties;
commit 1d11615cbe06f48f67b878dee28c9acd6a8834d8
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Fri Aug 9 11:42:47 2019 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:50 2020 +0200

    tdf#126723 writerfilter::finishParagraph - me, not previous
    
    In LO 6.2 commit 480ac84f2f5049fb4337b36f12fd6796e005761b
    the existing m_xPreviousParagraph was conveniently used to
    apply the changed properties. I never did like that choice,
    but despite looking at it, I failed to see that it is set
    in an inside loop, which means that it was NOT NECESSARILY
    reset to the current paragaph. So I'm happy to have proof
    that we should not use m_xPreviousParagraph.
    
    (cherry picked from commit 4c096b7e75a3c47abe4b3eb41183c133cb4cb441)
    
    Conflicts:
            sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
    
    Change-Id: I5c7f1b0f097711d65ae0d0be1f0fbc40c8b96e9d

diff --git a/sw/qa/extras/ooxmlexport/data/tdf126723.docx 
b/sw/qa/extras/ooxmlexport/data/tdf126723.docx
new file mode 100644
index 000000000000..297ea322fa7d
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf126723.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
index 3a22ffd2d6da..1833988a0b84 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
@@ -510,6 +510,11 @@ 
DECLARE_OOXMLEXPORT_TEST(testTdf119188_list_margin_in_cell, "tdf119188_list_marg
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), 
getProperty<sal_Int32>(getParagraphOfText(3, xCell->getText()), 
"ParaBottomMargin"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf126723, "tdf126723.docx")
+{
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraph(2), "ParaLeftMargin"));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 9b482e2f98c3..0838e1713967 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1417,39 +1417,40 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
                     }
                 }
 
+                css::uno::Reference<css::beans::XPropertySet> 
xParaProps(xTextRange, uno::UNO_QUERY);
                 // tdf#118521 set paragraph top or bottom margin based on the 
paragraph style
                 // if we already set the other margin with direct formatting
-                if ( pParaContext && m_xPreviousParagraph.is() )
+                if (xParaProps)
                 {
                     const bool bTopSet = 
pParaContext->isSet(PROP_PARA_TOP_MARGIN);
                     const bool bBottomSet = 
pParaContext->isSet(PROP_PARA_BOTTOM_MARGIN);
                     const bool bContextSet = 
pParaContext->isSet(PROP_PARA_CONTEXT_MARGIN);
                     if ( !(bTopSet == bBottomSet && bBottomSet == bContextSet) 
)
                     {
+
                         if ( !bTopSet )
                         {
                             uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_TOP_MARGIN);
                             if ( aMargin != uno::Any() )
-                                
m_xPreviousParagraph->setPropertyValue("ParaTopMargin", aMargin);
+                                xParaProps->setPropertyValue("ParaTopMargin", 
aMargin);
                         }
                         if ( !bBottomSet )
                         {
                             uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_BOTTOM_MARGIN);
                             if ( aMargin != uno::Any() )
-                                
m_xPreviousParagraph->setPropertyValue("ParaBottomMargin", aMargin);
+                                
xParaProps->setPropertyValue("ParaBottomMargin", aMargin);
                         }
                         if ( !bContextSet )
                         {
                             uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_CONTEXT_MARGIN);
                             if ( aMargin != uno::Any() )
-                                
m_xPreviousParagraph->setPropertyValue("ParaContextMargin", aMargin);
+                                
xParaProps->setPropertyValue("ParaContextMargin", aMargin);
                         }
                     }
                 }
 
                 // Left, Right, and Hanging settings are also grouped. Ensure 
that all or none are set.
-                // m_xPreviousParagraph was set earlier, so really it still is 
the current paragraph...
-                if ( pParaContext && m_xPreviousParagraph.is() )
+                if (xParaProps)
                 {
                     const bool bLeftSet  = 
pParaContext->isSet(PROP_PARA_LEFT_MARGIN);
                     const bool bRightSet = 
pParaContext->isSet(PROP_PARA_RIGHT_MARGIN);
@@ -1460,19 +1461,19 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
                         {
                             uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_LEFT_MARGIN);
                             if ( aMargin != uno::Any() )
-                                
m_xPreviousParagraph->setPropertyValue("ParaLeftMargin", aMargin);
+                                xParaProps->setPropertyValue("ParaLeftMargin", 
aMargin);
                         }
                         if ( !bRightSet )
                         {
                             uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_RIGHT_MARGIN);
                             if ( aMargin != uno::Any() )
-                                
m_xPreviousParagraph->setPropertyValue("ParaRightMargin", aMargin);
+                                
xParaProps->setPropertyValue("ParaRightMargin", aMargin);
                         }
                         if ( !bFirstSet )
                         {
                             uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_FIRST_LINE_INDENT);
                             if ( aMargin != uno::Any() )
-                                
m_xPreviousParagraph->setPropertyValue("ParaFirstLineIndent", aMargin);
+                                
xParaProps->setPropertyValue("ParaFirstLineIndent", aMargin);
                         }
                     }
                 }
commit 7ee01741796fb2e1cae0e0d061e7cb2eb305ea10
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Fri Aug 10 11:49:14 2018 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:50 2020 +0200

    tdf#119188 DOCX import: fix zero margins of numbered lines in cells
    
    regression from 5c6bce38a01b21403a603acd3148cf3bbb4c685f
    (tdf#104354 DOCX import: fix paragraph auto spacing in tables).
    
    (cherry picked from commit 5e2caf236091c71b2148970eba36b22655d8845a)
    
    Conflicts:
            sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
    
    Change-Id: I486d155eb4463599ab922837fd2f4347b48e0851

diff --git a/sw/qa/extras/ooxmlexport/data/tdf119188_list_margin_in_cell.docx 
b/sw/qa/extras/ooxmlexport/data/tdf119188_list_margin_in_cell.docx
new file mode 100644
index 000000000000..02b538685f47
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf119188_list_margin_in_cell.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
index 8ac0df32ebf3..3a22ffd2d6da 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
@@ -491,6 +491,25 @@ DECLARE_OOXMLEXPORT_TEST(testTdf118521_marginsLR, 
"tdf118521_marginsLR.docx")
     CPPUNIT_ASSERT_EQUAL(nMargin, getProperty<sal_Int32>(getParagraph(2), 
"ParaRightMargin"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf119188_list_margin_in_cell, 
"tdf119188_list_margin_in_cell.docx")
+{
+    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> 
xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+    uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), 
uno::UNO_QUERY);
+    uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), 
uno::UNO_QUERY);
+
+    // lists with auto margings in cells: top margin of the first paragraph is 
zero,
+    // but not the bottom margin of the last paragraph, also other list items 
have got
+    // zero margins.
+
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), 
"ParaTopMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), 
"ParaBottomMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), 
"ParaTopMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), 
"ParaBottomMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(3, xCell->getText()), 
"ParaTopMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), 
getProperty<sal_Int32>(getParagraphOfText(3, xCell->getText()), 
"ParaBottomMargin"));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 3f8ff43c510c..9b482e2f98c3 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1260,6 +1260,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
                 }
             }
             std::vector<beans::PropertyValue> aProperties;
+            bool bNumberedParagraph = false;
             if (pPropertyMap.get())
                 aProperties = comphelper::sequenceToContainer< 
std::vector<beans::PropertyValue> >(pPropertyMap->GetPropertyValues());
             if( !bIsDropCap )
@@ -1304,6 +1305,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
                     if (itNumberingRules != aProperties.end())
                     {
                         // This textnode has numbering. Look up the numbering 
style name of the current and previous paragraph.
+                        bNumberedParagraph = true;
                         OUString aCurrentNumberingRuleName;
                         uno::Reference<container::XNamed> 
xCurrentNumberingRules(itNumberingRules->Value, uno::UNO_QUERY);
                         if (xCurrentNumberingRules.is())
@@ -1386,8 +1388,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
                     uno::Reference< text::XTextRange > xParaEnd( xCur, 
uno::UNO_QUERY );
                     CheckParaMarkerRedline( xParaEnd );
                 }
-
-                // set top margin of the previous auto paragraph in cells, 
keeping zero bottom margin only at the first one
+                // set top margin of the previous auto paragraph in cells, 
keeping zero top margin only at the first one
                 if (m_nTableDepth > 0 && m_nTableDepth == m_nTableCellDepth && 
m_xPreviousParagraph.is())
                 {
                     bool bParaChangedTopMargin = false;
@@ -1409,7 +1410,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
 
                     if ((bPrevParaAutoBefore && !bParaChangedTopMargin) || 
(bParaChangedTopMargin && m_bParaAutoBefore))
                     {
-                        sal_Int32 nSize = m_bFirstParagraphInCell ? 0 : 280;
+                        sal_Int32 nSize = (m_bFirstParagraphInCell || 
bNumberedParagraph) ? 0 : 280;
                         // Previous before spacing is set to auto, set 
previous before space to 280, except in the first paragraph.
                         m_xPreviousParagraph->setPropertyValue("ParaTopMargin",
                                  uno::makeAny( 
ConversionHelper::convertTwipToMM100(nSize)));
commit e38e5d788c2f1e8b9ba90abc7ae9623bb8539f31
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Tue Jul 24 14:49:00 2018 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:50 2020 +0200

    tdf#118521 writerfilter: ContextMargin grouped with Top/Bottom
    
    fixes tdf#104348, but tagging with the bug# of the initial fixes.
    
    Internally, EditEng holds Top/Bottom/Context settings in one
    object, so if only one piece is set, the cloned object
    starts with docDefaults, so the un-initialized parts also need to
    be specified with the values they inherit from their style.
    
    So this patch makes two corrections. The first is grouping
    ContextMargin with top/bottom. The second correction
    is to check the entire style-chain instead of only
    the direct style for the inherited property.
    
    Change-Id: Ie1d4c9538aefece4ff8b7287242c7f4d33319b3b
    Reviewed-on: https://gerrit.libreoffice.org/57914
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <justin_l...@sil.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit 07266e2314fd19dcbf777dadd52d7b826b23c207)

diff --git a/sw/qa/extras/ooxmlexport/data/tdf104348_contextMargin.docx 
b/sw/qa/extras/ooxmlexport/data/tdf104348_contextMargin.docx
new file mode 100644
index 000000000000..ef3d06533bb7
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf104348_contextMargin.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
index 3159a14c7953..8ac0df32ebf3 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
@@ -462,6 +462,18 @@ DECLARE_OOXMLEXPORT_TEST(testTdf117504_numberingIndent, 
"tdf117504_numberingInde
     CPPUNIT_ASSERT_MESSAGE("Paragraph has numbering style", !sName.isEmpty());
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf104348_contextMargin, 
"tdf104348_contextMargin.docx")
+{
+    // tdf#104348 shows that ContextMargin belongs with Top/Bottom handling
+
+    uno::Reference<beans::XPropertySet> 
xMyStyle(getStyles("ParagraphStyles")->getByName("MyStyle"), uno::UNO_QUERY);
+    // from paragraph style - this is what direct formatting should equal
+    sal_Int32 nMargin = getProperty<sal_Int32>(xMyStyle, "ParaBottomMargin");
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nMargin);
+    // from direct formatting
+    CPPUNIT_ASSERT_EQUAL(nMargin, getProperty<sal_Int32>(getParagraph(2), 
"ParaBottomMargin"));
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf118521_marginsLR, "tdf118521_marginsLR.docx")
 {
     // tdf#118521 paragraphs with direct formatting of only some of left, 
right, or first margins have
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 10f0ff74c55a..3f8ff43c510c 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1418,46 +1418,60 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
 
                 // tdf#118521 set paragraph top or bottom margin based on the 
paragraph style
                 // if we already set the other margin with direct formatting
-                if (pStyleSheetProperties && pParaContext && 
m_xPreviousParagraph.is() &&
-                        pParaContext->isSet(PROP_PARA_TOP_MARGIN) != 
pParaContext->isSet(PROP_PARA_BOTTOM_MARGIN))
+                if ( pParaContext && m_xPreviousParagraph.is() )
                 {
-                    boost::optional<PropertyMap::Property> oProperty;
-                    if (pParaContext->isSet(PROP_PARA_TOP_MARGIN))
+                    const bool bTopSet = 
pParaContext->isSet(PROP_PARA_TOP_MARGIN);
+                    const bool bBottomSet = 
pParaContext->isSet(PROP_PARA_BOTTOM_MARGIN);
+                    const bool bContextSet = 
pParaContext->isSet(PROP_PARA_CONTEXT_MARGIN);
+                    if ( !(bTopSet == bBottomSet && bBottomSet == bContextSet) 
)
                     {
-                        if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_BOTTOM_MARGIN)) )
-                            
m_xPreviousParagraph->setPropertyValue("ParaBottomMargin", oProperty->second);
-                    }
-                    else
-                    {
-                        if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_TOP_MARGIN)) )
-                            
m_xPreviousParagraph->setPropertyValue("ParaTopMargin", oProperty->second);
+                        if ( !bTopSet )
+                        {
+                            uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_TOP_MARGIN);
+                            if ( aMargin != uno::Any() )
+                                
m_xPreviousParagraph->setPropertyValue("ParaTopMargin", aMargin);
+                        }
+                        if ( !bBottomSet )
+                        {
+                            uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_BOTTOM_MARGIN);
+                            if ( aMargin != uno::Any() )
+                                
m_xPreviousParagraph->setPropertyValue("ParaBottomMargin", aMargin);
+                        }
+                        if ( !bContextSet )
+                        {
+                            uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_CONTEXT_MARGIN);
+                            if ( aMargin != uno::Any() )
+                                
m_xPreviousParagraph->setPropertyValue("ParaContextMargin", aMargin);
+                        }
                     }
                 }
 
                 // Left, Right, and Hanging settings are also grouped. Ensure 
that all or none are set.
                 // m_xPreviousParagraph was set earlier, so really it still is 
the current paragraph...
-                if ( pStyleSheetProperties && pParaContext && 
m_xPreviousParagraph.is() )
+                if ( pParaContext && m_xPreviousParagraph.is() )
                 {
                     const bool bLeftSet  = 
pParaContext->isSet(PROP_PARA_LEFT_MARGIN);
                     const bool bRightSet = 
pParaContext->isSet(PROP_PARA_RIGHT_MARGIN);
                     const bool bFirstSet = 
pParaContext->isSet(PROP_PARA_FIRST_LINE_INDENT);
                     if ( !(bLeftSet == bRightSet && bRightSet == bFirstSet) )
                     {
-                        boost::optional<PropertyMap::Property> oProperty;
                         if ( !bLeftSet )
                         {
-                            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_LEFT_MARGIN)) )
-                                
m_xPreviousParagraph->setPropertyValue("ParaLeftMargin", oProperty->second);
+                            uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_LEFT_MARGIN);
+                            if ( aMargin != uno::Any() )
+                                
m_xPreviousParagraph->setPropertyValue("ParaLeftMargin", aMargin);
                         }
                         if ( !bRightSet )
                         {
-                            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_RIGHT_MARGIN)) )
-                                
m_xPreviousParagraph->setPropertyValue("ParaRightMargin", oProperty->second);
+                            uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_RIGHT_MARGIN);
+                            if ( aMargin != uno::Any() )
+                                
m_xPreviousParagraph->setPropertyValue("ParaRightMargin", aMargin);
                         }
                         if ( !bFirstSet )
                         {
-                            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_FIRST_LINE_INDENT)) )
-                                
m_xPreviousParagraph->setPropertyValue("ParaFirstLineIndent", 
oProperty->second);
+                            uno::Any aMargin = 
GetPropertyFromStyleSheet(PROP_PARA_FIRST_LINE_INDENT);
+                            if ( aMargin != uno::Any() )
+                                
m_xPreviousParagraph->setPropertyValue("ParaFirstLineIndent", aMargin);
                         }
                     }
                 }
commit 760c5f4066f2651ca8b4d4e0597e7b01062fcc5a
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Thu Jul 19 19:20:26 2018 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:50 2020 +0200

    tdf#118521 DOCX import: style sets unset left/right/hanging margin
    
    followup to commit 480ac84f2f5049fb4337b36f12fd6796e005761b which
    nicely paved the way by doing this for top/bottom.
    
    (cherry picked from commit eab67995d7056682c250efa3c903b1fffd812700)
    
    Conflicts:
            sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
    
    Change-Id: I61b4e298e8732391b4f0467b459d9c15298925fa

diff --git a/sw/qa/extras/ooxmlexport/data/tdf118521_marginsLR.docx 
b/sw/qa/extras/ooxmlexport/data/tdf118521_marginsLR.docx
new file mode 100644
index 000000000000..66170ede470c
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf118521_marginsLR.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
index 2d62c3f9f003..3159a14c7953 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
@@ -462,6 +462,23 @@ DECLARE_OOXMLEXPORT_TEST(testTdf117504_numberingIndent, 
"tdf117504_numberingInde
     CPPUNIT_ASSERT_MESSAGE("Paragraph has numbering style", !sName.isEmpty());
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf118521_marginsLR, "tdf118521_marginsLR.docx")
+{
+    // tdf#118521 paragraphs with direct formatting of only some of left, 
right, or first margins have
+    // lost the other unset margins coming from paragraph style, getting a bad 
margin from the default style instead
+
+    uno::Reference<beans::XPropertySet> 
xMyStyle(getStyles("ParagraphStyles")->getByName("MyStyle"), uno::UNO_QUERY);
+    // from paragraph style - this is what direct formatting should equal
+    sal_Int32 nMargin = getProperty<sal_Int32>(xMyStyle, "ParaLeftMargin");
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nMargin);
+    // from direct formatting
+    CPPUNIT_ASSERT_EQUAL(nMargin, getProperty<sal_Int32>(getParagraph(1), 
"ParaLeftMargin"));
+
+    nMargin = getProperty<sal_Int32>(xMyStyle, "ParaRightMargin");
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1900), nMargin);
+    CPPUNIT_ASSERT_EQUAL(nMargin, getProperty<sal_Int32>(getParagraph(2), 
"ParaRightMargin"));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index e61c0f722380..10f0ff74c55a 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1121,16 +1121,16 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
     TagLogger::getInstance().attribute("isTextAppend", 
sal_uInt32(xTextAppend.is()));
 #endif
 
+    const StyleSheetEntryPtr pEntry = 
GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( 
GetCurrentParaStyleName() );
+    OSL_ENSURE( pEntry.get(), "no style sheet found" );
+    const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const 
StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : nullptr);
     //apply numbering to paragraph if it was set at the style, but only if the 
paragraph itself
     //does not specify the numbering
-    if( pParaContext && !pParaContext->isSet(PROP_NUMBERING_RULES) )
+    if ( pStyleSheetProperties && pParaContext && 
!pParaContext->isSet(PROP_NUMBERING_RULES) )
     {
-        const StyleSheetEntryPtr pEntry = 
GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( 
GetCurrentParaStyleName() );
-        OSL_ENSURE( pEntry.get(), "no style sheet found" );
-        const StyleSheetPropertyMap* pStyleSheetProperties = 
dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : 
nullptr);
 
         sal_Int32 nListId = pEntry ? lcl_getListId(pEntry, 
GetStyleSheetTable()) : -1;
-        if( pStyleSheetProperties && nListId >= 0 )
+        if ( nListId >= 0 )
         {
             if ( !pEntry->bIsChapterNumbering )
                 pParaContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( 
ListDef::GetStyleName( nListId ) ), false);
@@ -1169,7 +1169,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
             }
         }
 
-        if( pStyleSheetProperties && pStyleSheetProperties->GetListLevel() >= 
0 )
+        if ( pStyleSheetProperties->GetListLevel() >= 0 )
             pParaContext->Insert( PROP_NUMBERING_LEVEL, 
uno::makeAny(pStyleSheetProperties->GetListLevel()), false);
     }
 
@@ -1418,28 +1418,49 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
 
                 // tdf#118521 set paragraph top or bottom margin based on the 
paragraph style
                 // if we already set the other margin with direct formatting
-                if (pParaContext && m_xPreviousParagraph.is() &&
+                if (pStyleSheetProperties && pParaContext && 
m_xPreviousParagraph.is() &&
                         pParaContext->isSet(PROP_PARA_TOP_MARGIN) != 
pParaContext->isSet(PROP_PARA_BOTTOM_MARGIN))
                 {
-                    const StyleSheetEntryPtr pEntry = 
GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( 
GetCurrentParaStyleName() );
-                    OSL_ENSURE( pEntry.get(), "no style sheet found" );
-                    const StyleSheetPropertyMap* pStyleSheetProperties =
-                            dynamic_cast<const StyleSheetPropertyMap*>(pEntry 
? pEntry->pProperties.get() : nullptr);
-                    if (pStyleSheetProperties) {
+                    boost::optional<PropertyMap::Property> oProperty;
+                    if (pParaContext->isSet(PROP_PARA_TOP_MARGIN))
+                    {
+                        if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_BOTTOM_MARGIN)) )
+                            
m_xPreviousParagraph->setPropertyValue("ParaBottomMargin", oProperty->second);
+                    }
+                    else
+                    {
+                        if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_TOP_MARGIN)) )
+                            
m_xPreviousParagraph->setPropertyValue("ParaTopMargin", oProperty->second);
+                    }
+                }
+
+                // Left, Right, and Hanging settings are also grouped. Ensure 
that all or none are set.
+                // m_xPreviousParagraph was set earlier, so really it still is 
the current paragraph...
+                if ( pStyleSheetProperties && pParaContext && 
m_xPreviousParagraph.is() )
+                {
+                    const bool bLeftSet  = 
pParaContext->isSet(PROP_PARA_LEFT_MARGIN);
+                    const bool bRightSet = 
pParaContext->isSet(PROP_PARA_RIGHT_MARGIN);
+                    const bool bFirstSet = 
pParaContext->isSet(PROP_PARA_FIRST_LINE_INDENT);
+                    if ( !(bLeftSet == bRightSet && bRightSet == bFirstSet) )
+                    {
                         boost::optional<PropertyMap::Property> oProperty;
-                        if (pParaContext->isSet(PROP_PARA_TOP_MARGIN))
+                        if ( !bLeftSet )
                         {
-                            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_BOTTOM_MARGIN)) )
-                                
m_xPreviousParagraph->setPropertyValue("ParaBottomMargin", oProperty->second);
+                            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_LEFT_MARGIN)) )
+                                
m_xPreviousParagraph->setPropertyValue("ParaLeftMargin", oProperty->second);
                         }
-                        else
+                        if ( !bRightSet )
                         {
-                            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_TOP_MARGIN)) )
-                                
m_xPreviousParagraph->setPropertyValue("ParaTopMargin", oProperty->second);
+                            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_RIGHT_MARGIN)) )
+                                
m_xPreviousParagraph->setPropertyValue("ParaRightMargin", oProperty->second);
+                        }
+                        if ( !bFirstSet )
+                        {
+                            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_FIRST_LINE_INDENT)) )
+                                
m_xPreviousParagraph->setPropertyValue("ParaFirstLineIndent", 
oProperty->second);
                         }
                     }
                 }
-
             }
             if( !bKeepLastParagraphProperties )
                 rAppendContext.pLastParagraphProperties = pToBeSavedProperties;
commit 874e7b448ee216893ea26bb490d34a3d1ab91b61
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Tue Jul 17 19:46:22 2018 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:50 2020 +0200

    tdf#118521 DOCX import: fix paragraph margin from paragraph style
    
    when the other (top or bottom) margin was set by direct formatting.
    
    Change-Id: Ic4038397329374fb2d6cf974751310f7dd8e8b31
    Reviewed-on: https://gerrit.libreoffice.org/57585
    Tested-by: Jenkins
    Reviewed-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit dc0300eac3b755bc207cd1fe87217f4ebaeb9f58)

diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 3cc02e469b00..e61c0f722380 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1415,6 +1415,31 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
                                  uno::makeAny( 
ConversionHelper::convertTwipToMM100(nSize)));
                     }
                 }
+
+                // tdf#118521 set paragraph top or bottom margin based on the 
paragraph style
+                // if we already set the other margin with direct formatting
+                if (pParaContext && m_xPreviousParagraph.is() &&
+                        pParaContext->isSet(PROP_PARA_TOP_MARGIN) != 
pParaContext->isSet(PROP_PARA_BOTTOM_MARGIN))
+                {
+                    const StyleSheetEntryPtr pEntry = 
GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( 
GetCurrentParaStyleName() );
+                    OSL_ENSURE( pEntry.get(), "no style sheet found" );
+                    const StyleSheetPropertyMap* pStyleSheetProperties =
+                            dynamic_cast<const StyleSheetPropertyMap*>(pEntry 
? pEntry->pProperties.get() : nullptr);
+                    if (pStyleSheetProperties) {
+                        boost::optional<PropertyMap::Property> oProperty;
+                        if (pParaContext->isSet(PROP_PARA_TOP_MARGIN))
+                        {
+                            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_BOTTOM_MARGIN)) )
+                                
m_xPreviousParagraph->setPropertyValue("ParaBottomMargin", oProperty->second);
+                        }
+                        else
+                        {
+                            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_TOP_MARGIN)) )
+                                
m_xPreviousParagraph->setPropertyValue("ParaTopMargin", oProperty->second);
+                        }
+                    }
+                }
+
             }
             if( !bKeepLastParagraphProperties )
                 rAppendContext.pLastParagraphProperties = pToBeSavedProperties;
commit 18d709afb444a245b3ef7d036f559d5bb4c43d28
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Thu May 10 15:36:11 2018 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:49 2020 +0200

    tdf#117504 ooxmlimport: check paragraph props for actual style
    
    m_sCurrentParaStyleName sounds like a nice idea, and has been
    around since the initial fork, but by the time finishParagraph()
    rolls around, the chances that it is still accurate are rather low.
    Anything that contains a paragraph (like comments, textboxes,
    shapes, tables, flys etc) might have modified that value.
    
    This fix queries the current paragraph itself to see if
    PROP_PARA_STYLE_NAME is set, which it typically is by
    lcl_startParagraphGroup() except when IsInShape().
    If it isn't specified, then fallback to the previous result, which
    still may not be accurate, but at least it won't be a regression.
    
    It is too late in the development cycle to look into fully
    eliminating m_sCurrentParaStyleName. I hope to investigate that
    in the 6.2 development cycle.
    
    (cherry picked from commit 8920d865ee148518bf71f71ce1866b24cc17c07e)
    
    Conflicts:
            sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
    
    Change-Id: I124688d864f553dd5778b3593f511cc41d31c262

diff --git a/sw/qa/extras/ooxmlexport/data/tdf117504_numberingIndent.docx 
b/sw/qa/extras/ooxmlexport/data/tdf117504_numberingIndent.docx
new file mode 100644
index 000000000000..091718984540
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf117504_numberingIndent.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
index a4e435c62f78..2d62c3f9f003 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
@@ -456,6 +456,12 @@ DECLARE_OOXMLIMPORT_TEST(testTdf128207, "tdf128207.docx")
     CPPUNIT_ASSERT_EQUAL(sal_Int32(12), getProperty<sal_Int32>(getShape(1), 
"HoriOrientPosition"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf117504_numberingIndent, 
"tdf117504_numberingIndent.docx")
+{
+    OUString sName = getProperty<OUString>(getParagraph(1), 
"NumberingStyleName");
+    CPPUNIT_ASSERT_MESSAGE("Paragraph has numbering style", !sName.isEmpty());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index cdc0fadaef64..3cc02e469b00 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -650,6 +650,17 @@ uno::Sequence< style::TabStop > 
DomainMapper_Impl::GetCurrentTabStopAndClear()
     return comphelper::containerToSequence(aRet);
 }
 
+const OUString DomainMapper_Impl::GetCurrentParaStyleName()
+{
+    // use saved currParaStyleName as a fallback, in case no particular para 
style name applied.
+    OUString sName = m_sCurrentParaStyleName;
+    PropertyMapPtr pParaContext = GetTopContextOfType(CONTEXT_PARAGRAPH);
+    if ( pParaContext && pParaContext->isSet(PROP_PARA_STYLE_NAME) )
+        pParaContext->getProperty(PROP_PARA_STYLE_NAME)->second >>= sName;
+
+    return sName;
+}
+
 /*-------------------------------------------------------------------------
     returns a the value from the current paragraph style - if available
     TODO: What about parent styles?
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 6a54487e1818..1b04f0a18f67 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -474,7 +474,7 @@ private:
     PropertyMapPtr           m_pLastCharacterContext;
 
     ::std::vector<DeletableTabStop> m_aCurrentTabStops;
-    OUString                        m_sCurrentParaStyleName;
+    OUString                        m_sCurrentParaStyleName; //highly 
inaccurate. Overwritten by "overlapping" paragraphs like comments, flys.
     bool                            m_bInStyleSheetImport; //in import of 
fonts, styles, lists or lfos
     bool                            m_bInAnyTableImport; //in import of fonts, 
styles, lists or lfos
     bool                            m_bInHeaderFooterImport;
@@ -694,7 +694,7 @@ public:
     css::uno::Sequence<css::style::TabStop> GetCurrentTabStopAndClear();
 
     void            SetCurrentParaStyleName(const OUString& sStringValue) 
{m_sCurrentParaStyleName = sStringValue;}
-    const OUString& GetCurrentParaStyleName() const {return 
m_sCurrentParaStyleName;}
+    const OUString  GetCurrentParaStyleName();
 
     css::uno::Any GetPropertyFromStyleSheet(PropertyIds eId);
     void        SetStyleSheetImport( bool bSet ) { m_bInStyleSheetImport = 
bSet;}
commit 4afd0c5935655d5073495b3461123a2ce5de87c1
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Wed May 9 18:43:54 2018 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:49 2020 +0200

    writerfilter NFC: save ConvertedParaStyleName, not WW8Name
    
    and rename m_sCurrentParaStyleId -> m_sCurrentParaStyleName
    
    This is prep work for tdf#117504, where the value
    saved in m_sCurrentParaStyleId is not accurate. Since the
    actual value saved inside the paragraph properties is the
    ConvertStyleName(), lets use the LO-version of the
    style name, so that FindStyleSheetByConvertedStyleName()
    can be used for either the paragraph's PropertyValue or
    m_pImpl->m_sCurrentParaStyleName.
    
    Change-Id: I8aed80094417ea91f2515e666dc05ecbb021a128
    Reviewed-on: https://gerrit.libreoffice.org/54084
    Reviewed-by: Justin Luth <justin_l...@sil.org>
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk>
    Tested-by: Miklos Vajna <vmik...@collabora.co.uk>
    (cherry picked from commit 36839898fadddee155fb73e70d16e1eea4f5f9f0)

diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 6036d8214214..9b8c443cff7e 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2118,9 +2118,9 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
     break;
     case NS_ooxml::LN_CT_PPrBase_pStyle:
     {
-        m_pImpl->SetCurrentParaStyleId( sStringValue );
         StyleSheetTablePtr pStyleTable = m_pImpl->GetStyleSheetTable();
         const OUString sConvertedStyleName = pStyleTable->ConvertStyleName( 
sStringValue, true );
+        m_pImpl->SetCurrentParaStyleName( sConvertedStyleName );
         if (m_pImpl->GetTopContext() && m_pImpl->GetTopContextType() != 
CONTEXT_SECTION)
         {
             m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, 
uno::makeAny( sConvertedStyleName ));
@@ -2943,7 +2943,7 @@ void DomainMapper::lcl_startParagraphGroup()
         if (!m_pImpl->IsInShape())
         {
             m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, 
uno::makeAny( OUString("Standard") ) ); //ConvertedStyleName
-            m_pImpl->SetCurrentParaStyleId("Normal"); //WW8 name
+            m_pImpl->SetCurrentParaStyleName("Standard");
         }
         if (m_pImpl->isBreakDeferred(PAGE_BREAK))
             m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, 
uno::makeAny(style::BreakType_PAGE_BEFORE));
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index f2666484e420..cdc0fadaef64 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -203,7 +203,7 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_sCurrentPermId(0),
         m_pLastSectionContext( ),
         m_pLastCharacterContext(),
-        m_sCurrentParaStyleId(),
+        m_sCurrentParaStyleName(),
         m_bInStyleSheetImport( false ),
         m_bInAnyTableImport( false ),
         m_bInHeaderFooterImport( false ),
@@ -660,8 +660,7 @@ uno::Any 
DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId)
     if( m_bInStyleSheetImport )
         pEntry = GetStyleSheetTable()->FindParentStyleSheet(OUString());
     else
-        pEntry =
-                
GetStyleSheetTable()->FindStyleSheetByISTD(GetCurrentParaStyleId());
+        pEntry = 
GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(GetCurrentParaStyleName());
     while(pEntry.get( ) )
     {
         //is there a tab stop set?
@@ -1115,7 +1114,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
     //does not specify the numbering
     if( pParaContext && !pParaContext->isSet(PROP_NUMBERING_RULES) )
     {
-        const StyleSheetEntryPtr pEntry = 
GetStyleSheetTable()->FindStyleSheetByISTD( GetCurrentParaStyleId() );
+        const StyleSheetEntryPtr pEntry = 
GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( 
GetCurrentParaStyleName() );
         OSL_ENSURE( pEntry.get(), "no style sheet found" );
         const StyleSheetPropertyMap* pStyleSheetProperties = 
dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : 
nullptr);
 
@@ -5585,10 +5584,10 @@ uno::Reference<container::XIndexAccess> 
DomainMapper_Impl::GetCurrentNumberingRu
     uno::Reference<container::XIndexAccess> xRet;
     try
     {
-        OUString aStyle = GetCurrentParaStyleId();
+        OUString aStyle = GetCurrentParaStyleName();
         if (aStyle.isEmpty())
             return xRet;
-        const StyleSheetEntryPtr pEntry = 
GetStyleSheetTable()->FindStyleSheetByISTD(aStyle);
+        const StyleSheetEntryPtr pEntry = 
GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(aStyle);
         if (!pEntry)
             return xRet;
         const StyleSheetPropertyMap* pStyleSheetProperties = 
dynamic_cast<const StyleSheetPropertyMap*>(pEntry->pProperties.get());
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 12516e8f84b6..6a54487e1818 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -474,7 +474,7 @@ private:
     PropertyMapPtr           m_pLastCharacterContext;
 
     ::std::vector<DeletableTabStop> m_aCurrentTabStops;
-    OUString                 m_sCurrentParaStyleId;
+    OUString                        m_sCurrentParaStyleName;
     bool                            m_bInStyleSheetImport; //in import of 
fonts, styles, lists or lfos
     bool                            m_bInAnyTableImport; //in import of fonts, 
styles, lists or lfos
     bool                            m_bInHeaderFooterImport;
@@ -693,8 +693,8 @@ public:
     void    IncorporateTabStop( const DeletableTabStop &aTabStop );
     css::uno::Sequence<css::style::TabStop> GetCurrentTabStopAndClear();
 
-    void        SetCurrentParaStyleId(const OUString& sStringValue) 
{m_sCurrentParaStyleId = sStringValue;}
-    const OUString& GetCurrentParaStyleId() const {return 
m_sCurrentParaStyleId;}
+    void            SetCurrentParaStyleName(const OUString& sStringValue) 
{m_sCurrentParaStyleName = sStringValue;}
+    const OUString& GetCurrentParaStyleName() const {return 
m_sCurrentParaStyleName;}
 
     css::uno::Any GetPropertyFromStyleSheet(PropertyIds eId);
     void        SetStyleSheetImport( bool bSet ) { m_bInStyleSheetImport = 
bSet;}
commit 807469d9663e73301b728499b11ecf436f5d3bd3
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Wed Jan 17 16:25:56 2018 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:49 2020 +0200

    writerfilter: move TopContextType==Para requirement
    
    This is prep work for tdf#95377. I need this function to
    run when there is no TopContext. This function doesn't do anything
    with the context, so in that regard I wonder if it is even
    necessary? My guess would be that it is a leftover piece from
    discovering the fix for n75883.
    
    However, to avoid causing a regression, I'm just pulling this test
    into the calling functions. (Of the three instances
    calling this function, two need to be contextless..)
    
    This is not truly NFC because if the followup patch is reverted,
    then this one will cause a change. But that is actually OK, because
    if my follow-up patch breaks because of these two functions changing
    to become contextless, then I'll be better able to pin-point the
    reason for the regression.
    
    Original commit adding this function was
    commit 2123ede032ca64f696ef54af4ad3238974ca2b5d
    
    Change-Id: I471aa852aa48527d69e0343a2ac28fa6e8acb209
    Reviewed-on: https://gerrit.libreoffice.org/48062
    Reviewed-by: Justin Luth <justin_l...@sil.org>
    Tested-by: Justin Luth <justin_l...@sil.org>
    (cherry picked from commit 254c80037a3939c110d5c66fef6c28caf47625e5)

diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 20d371ed21e6..f2666484e420 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -5586,7 +5586,7 @@ uno::Reference<container::XIndexAccess> 
DomainMapper_Impl::GetCurrentNumberingRu
     try
     {
         OUString aStyle = GetCurrentParaStyleId();
-        if (aStyle.isEmpty() || GetTopContextType() != CONTEXT_PARAGRAPH)
+        if (aStyle.isEmpty())
             return xRet;
         const StyleSheetEntryPtr pEntry = 
GetStyleSheetTable()->FindStyleSheetByISTD(aStyle);
         if (!pEntry)
@@ -5623,7 +5623,9 @@ uno::Reference<beans::XPropertySet> 
DomainMapper_Impl::GetCurrentNumberingCharSt
     try
     {
         sal_Int32 nListLevel = -1;
-        uno::Reference<container::XIndexAccess> xLevels = 
GetCurrentNumberingRules(&nListLevel);
+        uno::Reference<container::XIndexAccess> xLevels;
+        if ( GetTopContextType() == CONTEXT_PARAGRAPH )
+            xLevels = GetCurrentNumberingRules(&nListLevel);
         if (!xLevels.is())
         {
             PropertyMapPtr pContext = m_pTopContext;
commit a105dc2c718ce119d93efdefde00bc551b631cc8
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Tue Jan 23 21:56:00 2018 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:49 2020 +0200

    tdf#95377 ooxmlimport: treat default style like named styles
    
    The default style was missing out on all of the fixes made
    by LN_CT_PPrBase_pStyle. That included right margins, and
    numbering styles.
    
    Essentially, this change is just copy and paste from one function
    to another. I tried to make all of the logic changes
    separately in previous commits. So the adjustments here are simply
    to accommodate different variable/function names. So if this
    causes any regressions, it ought to just be related to either
    applying later on (at finishparagraph instead of
    LN_CT_PPrBase_pStyle or because it includes the default style.
    
    One important note regards the preparatory
    commit 254c80037a3939c110d5c66fef6c28caf47625e5.
    If this commit is reverted, make sure to check that commit
    to add a conditional wrappers around GetCurrentNumberingRules().
    
    (cherry picked from commit cc1c9c7484d97167021301f32c3397124c4d79f5)
    
    Conflicts:
            writerfilter/source/dmapper/DomainMapper.cxx
    
    Change-Id: I9827b2cd1a74a13cf18ada9baa221c5c567a7391

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
index 4ef0e616c8ec..599cdf806cce 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
@@ -921,6 +921,14 @@ DECLARE_OOXMLEXPORT_TEST(testTdf95377, "tdf95377.docx")
     CPPUNIT_ASSERT_EQUAL(sal_Int32(-250), getProperty<sal_Int32>(xParagraph, 
"ParaFirstLineIndent"));
     CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty<sal_Int32>(xParagraph, 
"ParaLeftMargin"));
     CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, 
xParagraph->getPropertyState("ParaFirstLineIndent"));
+
+    //default style has numbering enabled.  Styles inherit numbering unless 
specifically disabled
+    xmlDocPtr pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "//body/txt/Special", 3);  //first three paragraphs 
have numbering
+    assertXPath(pXmlDoc, "//body/txt[1]/Special", "rText", "a.");
+    assertXPath(pXmlDoc, "//body/txt[2]/Special", "rText", "b.");
+    assertXPath(pXmlDoc, "//body/txt[3]/Special", "rText", "c.");
+    assertXPath(pXmlDoc, "/root/page/body/txt[4]/Special", 0); //last 
paragraph style disables numbering
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf95376, "tdf95376.docx")
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 34a21683e3d4..6036d8214214 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1204,30 +1204,6 @@ static bool ExchangeLeftRight(const PropertyMapPtr& 
rContext, DomainMapper_Impl&
     return bExchangeLeftRight;
 }
 
-/// Check if the style or its parent has a list id, recursively.
-static sal_Int32 lcl_getListId(const StyleSheetEntryPtr& rEntry, const 
StyleSheetTablePtr& rStyleTable)
-{
-    const StyleSheetPropertyMap* pEntryProperties = dynamic_cast<const 
StyleSheetPropertyMap*>(rEntry->pProperties.get());
-    if (!pEntryProperties)
-        return -1;
-
-    sal_Int32 nListId = pEntryProperties->GetListId();
-    // The style itself has a list id.
-    if (nListId >= 0)
-        return nListId;
-
-    // The style has no parent.
-    if (rEntry->sBaseStyleIdentifier.isEmpty())
-        return -1;
-
-    const StyleSheetEntryPtr pParent = 
rStyleTable->FindStyleSheetByISTD(rEntry->sBaseStyleIdentifier);
-    // No such parent style or loop in the style hierarchy.
-    if (!pParent || pParent == rEntry)
-        return -1;
-
-    return lcl_getListId(pParent, rStyleTable);
-}
-
 void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
 {
     // These SPRM's are not specific to any section, so it's expected that 
there is no context yet.
@@ -2167,57 +2143,6 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
                 }
             }
         }
-        //apply numbering to paragraph if it was set at the style, but only if 
the paragraph itself
-        //does not specify the numbering
-        if( !rContext->isSet(PROP_NUMBERING_RULES) ) // !contains
-        {
-            const StyleSheetEntryPtr pEntry = 
pStyleTable->FindStyleSheetByISTD(sStringValue);
-            OSL_ENSURE( pEntry.get(), "no style sheet found" );
-            const StyleSheetPropertyMap* pStyleSheetProperties = 
dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : 
nullptr);
-
-            sal_Int32 nListId = pEntry ? lcl_getListId(pEntry, pStyleTable) : 
-1;
-            if( pStyleSheetProperties && nListId >= 0 )
-            {
-                if ( !pEntry->bIsChapterNumbering )
-                    rContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( 
ListDef::GetStyleName( nListId ) ), false);
-
-                // Indent properties from the paragraph style have priority
-                // over the ones from the numbering styles in Word
-                // but in Writer numbering styles have priority,
-                // so insert directly into the paragraph properties to 
compensate.
-                boost::optional<PropertyMap::Property> oProperty;
-                if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_FIRST_LINE_INDENT)) )
-                    rContext->Insert(PROP_PARA_FIRST_LINE_INDENT, 
oProperty->second, /*bOverwrite=*/false);
-                if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_LEFT_MARGIN)) )
-                    rContext->Insert(PROP_PARA_LEFT_MARGIN, oProperty->second, 
/*bOverwrite=*/false);
-
-                // We're inheriting properties from a numbering style. Make 
sure a possible right margin is inherited from the base style.
-                sal_Int32 nParaRightMargin = 0;
-                if (!pEntry->sBaseStyleIdentifier.isEmpty())
-                {
-                    const StyleSheetEntryPtr pParent = 
pStyleTable->FindStyleSheetByISTD(pEntry->sBaseStyleIdentifier);
-                    const StyleSheetPropertyMap* pParentProperties = 
dynamic_cast<const StyleSheetPropertyMap*>(pParent ? pParent->pProperties.get() 
: nullptr);
-                    boost::optional<PropertyMap::Property> pPropMargin;
-                    if (pParentProperties && (pPropMargin = 
pParentProperties->getProperty(PROP_PARA_RIGHT_MARGIN)) )
-                        nParaRightMargin = 
pPropMargin->second.get<sal_Int32>();
-                }
-                if (nParaRightMargin != 0)
-                {
-                    // If we're setting the right margin, we should set the 
first / left margin as well from the numbering style.
-                    const sal_Int32 nFirstLineIndent = 
m_pImpl->getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), 
"FirstLineIndent");
-                    const sal_Int32 nParaLeftMargin  = 
m_pImpl->getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), 
"IndentAt");
-                    if (nFirstLineIndent != 0)
-                        rContext->Insert(PROP_PARA_FIRST_LINE_INDENT, 
uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false);
-                    if (nParaLeftMargin != 0)
-                        rContext->Insert(PROP_PARA_LEFT_MARGIN, 
uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false);
-
-                    rContext->Insert(PROP_PARA_RIGHT_MARGIN, 
uno::makeAny(nParaRightMargin), /*bOverwrite=*/false);
-                }
-            }
-
-            if( pStyleSheetProperties && pStyleSheetProperties->GetListLevel() 
>= 0 )
-                rContext->Insert( PROP_NUMBERING_LEVEL, 
uno::makeAny(pStyleSheetProperties->GetListLevel()), false);
-        }
     }
     break;
     case NS_ooxml::LN_EG_RPrBase_rStyle:
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 16cbfe10ade1..20d371ed21e6 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1069,6 +1069,30 @@ void 
DomainMapper_Impl::CheckUnregisteredFrameConversion( )
     }
 }
 
+/// Check if the style or its parent has a list id, recursively.
+static sal_Int32 lcl_getListId(const StyleSheetEntryPtr& rEntry, const 
StyleSheetTablePtr& rStyleTable)
+{
+    const StyleSheetPropertyMap* pEntryProperties = dynamic_cast<const 
StyleSheetPropertyMap*>(rEntry->pProperties.get());
+    if (!pEntryProperties)
+        return -1;
+
+    sal_Int32 nListId = pEntryProperties->GetListId();
+    // The style itself has a list id.
+    if (nListId >= 0)
+        return nListId;
+
+    // The style has no parent.
+    if (rEntry->sBaseStyleIdentifier.isEmpty())
+        return -1;
+
+    const StyleSheetEntryPtr pParent = 
rStyleTable->FindStyleSheetByISTD(rEntry->sBaseStyleIdentifier);
+    // No such parent style or loop in the style hierarchy.
+    if (!pParent || pParent == rEntry)
+        return -1;
+
+    return lcl_getListId(pParent, rStyleTable);
+}
+
 void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap )
 {
     if (m_bDiscardHeaderFooter)
@@ -1087,6 +1111,59 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
     TagLogger::getInstance().attribute("isTextAppend", 
sal_uInt32(xTextAppend.is()));
 #endif
 
+    //apply numbering to paragraph if it was set at the style, but only if the 
paragraph itself
+    //does not specify the numbering
+    if( pParaContext && !pParaContext->isSet(PROP_NUMBERING_RULES) )
+    {
+        const StyleSheetEntryPtr pEntry = 
GetStyleSheetTable()->FindStyleSheetByISTD( GetCurrentParaStyleId() );
+        OSL_ENSURE( pEntry.get(), "no style sheet found" );
+        const StyleSheetPropertyMap* pStyleSheetProperties = 
dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : 
nullptr);
+
+        sal_Int32 nListId = pEntry ? lcl_getListId(pEntry, 
GetStyleSheetTable()) : -1;
+        if( pStyleSheetProperties && nListId >= 0 )
+        {
+            if ( !pEntry->bIsChapterNumbering )
+                pParaContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( 
ListDef::GetStyleName( nListId ) ), false);
+
+            // Indent properties from the paragraph style have priority
+            // over the ones from the numbering styles in Word
+            // but in Writer numbering styles have priority,
+            // so insert directly into the paragraph properties to compensate.
+            boost::optional<PropertyMap::Property> oProperty;
+            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_FIRST_LINE_INDENT)) )
+                pParaContext->Insert(PROP_PARA_FIRST_LINE_INDENT, 
oProperty->second, /*bOverwrite=*/false);
+            if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_LEFT_MARGIN)) )
+                pParaContext->Insert(PROP_PARA_LEFT_MARGIN, oProperty->second, 
/*bOverwrite=*/false);
+
+            // We're inheriting properties from a numbering style. Make sure a 
possible right margin is inherited from the base style.
+            sal_Int32 nParaRightMargin = 0;
+            if (!pEntry->sBaseStyleIdentifier.isEmpty())
+            {
+                const StyleSheetEntryPtr pParent = 
GetStyleSheetTable()->FindStyleSheetByISTD(pEntry->sBaseStyleIdentifier);
+                const StyleSheetPropertyMap* pParentProperties = 
dynamic_cast<const StyleSheetPropertyMap*>(pParent ? pParent->pProperties.get() 
: nullptr);
+                boost::optional<PropertyMap::Property> pPropMargin;
+                if (pParentProperties && (pPropMargin = 
pParentProperties->getProperty(PROP_PARA_RIGHT_MARGIN)) )
+                    nParaRightMargin = pPropMargin->second.get<sal_Int32>();
+            }
+            if (nParaRightMargin != 0)
+            {
+                // If we're setting the right margin, we should set the first 
/ left margin as well from the numbering style.
+                const sal_Int32 nFirstLineIndent = 
getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), 
"FirstLineIndent");
+                const sal_Int32 nParaLeftMargin  = 
getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), 
"IndentAt");
+                if (nFirstLineIndent != 0)
+                    pParaContext->Insert(PROP_PARA_FIRST_LINE_INDENT, 
uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false);
+                if (nParaLeftMargin != 0)
+                    pParaContext->Insert(PROP_PARA_LEFT_MARGIN, 
uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false);
+
+                pParaContext->Insert(PROP_PARA_RIGHT_MARGIN, 
uno::makeAny(nParaRightMargin), /*bOverwrite=*/false);
+            }
+        }
+
+        if( pStyleSheetProperties && pStyleSheetProperties->GetListLevel() >= 
0 )
+            pParaContext->Insert( PROP_NUMBERING_LEVEL, 
uno::makeAny(pStyleSheetProperties->GetListLevel()), false);
+    }
+
+
     if (xTextAppend.is() && pParaContext && hasTableManager() && 
!getTableManager().isIgnore())
     {
         try
commit f8584dae6b1a719f21afe2e7d4918e2e71cc468f
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Fri Jan 12 20:44:06 2018 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:49 2020 +0200

    tdf#76817 ooxmlimport: connect Heading to existing numbers
    
    This fixes the inability to insert a numbered Heading into
    an existing sequence in an opened document. Before it would
    start a new sequence, but now it connects to / adjusts
    the other numbered Headings.
    
    LibreOffice has built-in handling for "Chapter Numbering".
    All of the formatting for this is tied to the paragraph stylename.
    
    Since MSO has a different structure, in docx format these
    are defined as "regular" styles with an OutlineLvl component.
    During import, that style information was copied to LO's special
    Outline chapter numbering style. *From this point on, the
    "regular" list style should no longer be referred to.* Numbering is only
    defined by the paragraph stylename (which by definition is "Heading X").
    
    The unit test I am hijacking has an unchangeable Paragraph Numbering
    style of "Outline Numbering" and not WWNumX. So, in reality the
    document ought to require the style name to be the internal Outline
    style like it originally was.
    A followup patch allows this to round-trip.
    
    Change-Id: If5d544529fa32d4abaa2b46403bc61c028e53f21
    Reviewed-on: https://gerrit.libreoffice.org/47827
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Justin Luth <justin_l...@sil.org>
    Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk>
    (cherry picked from commit 7201d157a2ff2f0a8b6bb8fa57e31871187cbc81)

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index a7cc6d905209..08bde4d2137b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -739,8 +739,7 @@ DECLARE_OOXMLEXPORT_TEST(testOOxmlOutlineNumberTypes, 
"outline-number-types.odt"
 
 DECLARE_OOXMLEXPORT_TEST(testNumParentStyle, "num-parent-style.docx")
 {
-    // This was "Outline", i.e. <w:numId> was not imported from the Heading 2 
paragraph style.
-    CPPUNIT_ASSERT(getProperty<OUString>(getParagraph(4), 
"NumberingStyleName").startsWith("WWNum"));
+    //CPPUNIT_ASSERT_EQUAL(OUString("Outline"), 
getProperty<OUString>(getParagraph(4), "NumberingStyleName"));
 }
 
 DECLARE_OOXMLEXPORT_TEST(testNumOverrideLvltext, "num-override-lvltext.docx")
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 2336f4d0b89c..34a21683e3d4 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2178,8 +2178,8 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
             sal_Int32 nListId = pEntry ? lcl_getListId(pEntry, pStyleTable) : 
-1;
             if( pStyleSheetProperties && nListId >= 0 )
             {
-                rContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny(
-                            ListDef::GetStyleName( nListId ) ), false);
+                if ( !pEntry->bIsChapterNumbering )
+                    rContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( 
ListDef::GetStyleName( nListId ) ), false);
 
                 // Indent properties from the paragraph style have priority
                 // over the ones from the numbering styles in Word
diff --git a/writerfilter/source/dmapper/NumberingManager.cxx 
b/writerfilter/source/dmapper/NumberingManager.cxx
index 89e910102ac0..0df034ee3643 100644
--- a/writerfilter/source/dmapper/NumberingManager.cxx
+++ b/writerfilter/source/dmapper/NumberingManager.cxx
@@ -625,6 +625,7 @@ void ListDef::CreateNumberingRules( DomainMapper& rDMapper,
                         xOutlines->getChapterNumberingRules( );
 
                     StyleSheetEntryPtr pParaStyle = pAbsLevel->GetParaStyle( );
+                    pParaStyle->bIsChapterNumbering = true;
                     
aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HEADING_STYLE_NAME),
 pParaStyle->sConvertedStyleName));
 
                     xOutlineRules->replaceByIndex(nLevel, 
uno::makeAny(comphelper::containerToSequence(aLvlProps)));
diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx 
b/writerfilter/source/dmapper/StyleSheetTable.cxx
index f74022af4dc9..e2bbd96c04fa 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.cxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.cxx
@@ -57,6 +57,7 @@ StyleSheetEntry::StyleSheetEntry() :
         sStyleIdentifierI()
         ,sStyleIdentifierD()
         ,bIsDefaultStyle(false)
+        ,bIsChapterNumbering(false)
         ,bInvalidHeight(false)
         ,bHasUPE(false)
         ,nStyleTypeCode(STYLE_TYPE_UNKNOWN)
@@ -74,8 +75,8 @@ StyleSheetEntry::~StyleSheetEntry()
 TableStyleSheetEntry::TableStyleSheetEntry( StyleSheetEntry const & rEntry ):
     StyleSheetEntry( )
 {
-
     bIsDefaultStyle = rEntry.bIsDefaultStyle;
+    bIsChapterNumbering = rEntry.bIsChapterNumbering;
     bInvalidHeight = rEntry.bInvalidHeight;
     bHasUPE = rEntry.bHasUPE;
     nStyleTypeCode = STYLE_TYPE_TABLE;
diff --git a/writerfilter/source/dmapper/StyleSheetTable.hxx 
b/writerfilter/source/dmapper/StyleSheetTable.hxx
index b9131c02b53c..3a85bfc077b0 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.hxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.hxx
@@ -56,6 +56,7 @@ public:
     OUString sStyleIdentifierI;
     OUString sStyleIdentifierD;
     bool            bIsDefaultStyle;
+    bool            bIsChapterNumbering;  //LO built-in Chapter Numbering 
"Outline" list style
     bool            bInvalidHeight;
     bool            bHasUPE; //universal property expansion
     StyleType       nStyleTypeCode; //sgc
commit ef1e1196cb4c04eaeffa51e8d9a470c0e5192f5f
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Tue Jan 23 14:41:48 2018 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:49 2020 +0200

    ooxmlimport: support inherited listid
    
    This is prep work for tdf#95377. This unit test avoids the unique
    chapter-numbering style (from the heading paragraph styles) and just
    has a basic, user-created style inheriting from Default.
    
    Also unique about this unit test is that the numbering is
    specified by the "Default Style" which takes a rather unique
    code path and exposes even more problems.
    
    We already know the listId through a recursive function, and
    GetCurrentNumberingRules only looks at the current style which
    isn't good enough. Moved that modified function into
    DomainMapper_Impl since I will need it there for bug 95377.
    
    Additionally, ensure that directly applied paragraph properties
    are not overwritten. That also meant changing the order, so that
    paraStyle properties are directly applied to the paragraph before
    applying RightMargin and friends.
    
    Change-Id: I5c1fb71d64727be9d9105f287150daf4e0ff413d
    Reviewed-on: https://gerrit.libreoffice.org/48457
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Justin Luth <justin_l...@sil.org>
    Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk>
    (cherry picked from commit 8fd13c356d78fb72ba5dd288a495551f23e15363)

diff --git a/sw/qa/extras/ooxmlexport/data/tdf95377.docx 
b/sw/qa/extras/ooxmlexport/data/tdf95377.docx
new file mode 100644
index 000000000000..be5551dca282
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf95377.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
index 370fe1ca8f97..4ef0e616c8ec 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
@@ -907,6 +907,22 @@ DECLARE_OOXMLEXPORT_TEST(testTdf92454, "tdf92454.docx")
     CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, 
xParagraph->getPropertyState("ParaFirstLineIndent"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf95377, "tdf95377.docx")
+{
+    uno::Reference<beans::XPropertyState> xParagraph(getParagraph(1), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), getProperty<sal_Int32>(xParagraph, 
"ParaRightMargin"));
+
+    xParagraph.set(getParagraph(2), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(-501), getProperty<sal_Int32>(xParagraph, 
"ParaFirstLineIndent"));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2501), getProperty<sal_Int32>(xParagraph, 
"ParaLeftMargin"));
+    CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, 
xParagraph->getPropertyState("ParaFirstLineIndent"));
+
+    xParagraph.set(getParagraph(3), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(-250), getProperty<sal_Int32>(xParagraph, 
"ParaFirstLineIndent"));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty<sal_Int32>(xParagraph, 
"ParaLeftMargin"));
+    CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, 
xParagraph->getPropertyState("ParaFirstLineIndent"));
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf95376, "tdf95376.docx")
 {
     uno::Reference<beans::XPropertyState> xParagraph(getParagraph(2), 
uno::UNO_QUERY);
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index daf6d09c2179..2336f4d0b89c 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1175,40 +1175,6 @@ void DomainMapper::lcl_sprm(Sprm & rSprm)
         sprmWithProps(rSprm, m_pImpl->GetTopContext());
 }
 
-sal_Int32 lcl_getCurrentNumberingProperty(
-        uno::Reference<container::XIndexAccess> const& xNumberingRules,
-        sal_Int32 nNumberingLevel, const OUString& aProp)
-{
-    sal_Int32 nRet = 0;
-
-    try
-    {
-        if (nNumberingLevel < 0) // It seems it's valid to omit numbering 
level, and in that case it means zero.
-            nNumberingLevel = 0;
-        if (xNumberingRules.is())
-        {
-            uno::Sequence<beans::PropertyValue> aProps;
-            xNumberingRules->getByIndex(nNumberingLevel) >>= aProps;
-            for (int i = 0; i < aProps.getLength(); ++i)
-            {
-                const beans::PropertyValue& rProp = aProps[i];
-
-                if (rProp.Name == aProp)
-                {
-                    rProp.Value >>= nRet;
-                    break;
-                }
-            }
-        }
-    }
-    catch( const uno::Exception& )
-    {
-        // This can happen when the doc contains some hand-crafted invalid 
list level.
-    }
-
-    return nRet;
-}
-
 // In rtl-paragraphs the meaning of left/right are to be exchanged
 static bool ExchangeLeftRight(const PropertyMapPtr& rContext, 
DomainMapper_Impl& rImpl)
 {
@@ -2215,6 +2181,16 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
                 rContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny(
                             ListDef::GetStyleName( nListId ) ), false);
 
+                // Indent properties from the paragraph style have priority
+                // over the ones from the numbering styles in Word
+                // but in Writer numbering styles have priority,
+                // so insert directly into the paragraph properties to 
compensate.
+                boost::optional<PropertyMap::Property> oProperty;
+                if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_FIRST_LINE_INDENT)) )
+                    rContext->Insert(PROP_PARA_FIRST_LINE_INDENT, 
oProperty->second, /*bOverwrite=*/false);
+                if ( (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_LEFT_MARGIN)) )
+                    rContext->Insert(PROP_PARA_LEFT_MARGIN, oProperty->second, 
/*bOverwrite=*/false);
+
                 // We're inheriting properties from a numbering style. Make 
sure a possible right margin is inherited from the base style.
                 sal_Int32 nParaRightMargin = 0;
                 if (!pEntry->sBaseStyleIdentifier.isEmpty())
@@ -2228,22 +2204,15 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
                 if (nParaRightMargin != 0)
                 {
                     // If we're setting the right margin, we should set the 
first / left margin as well from the numbering style.
-                    sal_Int32 nFirstLineIndent = 
lcl_getCurrentNumberingProperty(m_pImpl->GetCurrentNumberingRules(), 
pStyleSheetProperties->GetListLevel(), "FirstLineIndent");
-                    sal_Int32 nParaLeftMargin = 
lcl_getCurrentNumberingProperty(m_pImpl->GetCurrentNumberingRules(), 
pStyleSheetProperties->GetListLevel(), "IndentAt");
+                    const sal_Int32 nFirstLineIndent = 
m_pImpl->getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), 
"FirstLineIndent");
+                    const sal_Int32 nParaLeftMargin  = 
m_pImpl->getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), 
"IndentAt");
                     if (nFirstLineIndent != 0)
-                        rContext->Insert(PROP_PARA_FIRST_LINE_INDENT, 
uno::makeAny(nFirstLineIndent));
+                        rContext->Insert(PROP_PARA_FIRST_LINE_INDENT, 
uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false);
                     if (nParaLeftMargin != 0)
-                        rContext->Insert(PROP_PARA_LEFT_MARGIN, 
uno::makeAny(nParaLeftMargin));
+                        rContext->Insert(PROP_PARA_LEFT_MARGIN, 
uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false);
 
-                    rContext->Insert(PROP_PARA_RIGHT_MARGIN, 
uno::makeAny(nParaRightMargin));
+                    rContext->Insert(PROP_PARA_RIGHT_MARGIN, 
uno::makeAny(nParaRightMargin), /*bOverwrite=*/false);
                 }
-
-                // Indent properties from the paragraph style have priority
-                // over the ones from the numbering styles in Word, not in
-                // Writer.
-                boost::optional<PropertyMap::Property> oProperty;
-                if (pStyleSheetProperties && (oProperty = 
pStyleSheetProperties->getProperty(PROP_PARA_FIRST_LINE_INDENT)))
-                    rContext->Insert(PROP_PARA_FIRST_LINE_INDENT, 
oProperty->second);
             }
 
             if( pStyleSheetProperties && pStyleSheetProperties->GetListLevel() 
>= 0 )
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index e33085c21ff3..16cbfe10ade1 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -5631,6 +5631,48 @@ void 
DomainMapper_Impl::processDeferredCharacterProperties()
     }
 }
 
+sal_Int32 DomainMapper_Impl::getNumberingProperty(const sal_Int32 nListId, 
sal_Int32 nNumberingLevel, const OUString& aProp)
+{
+    sal_Int32 nRet = 0;
+    if ( nListId < 0 )
+        return nRet;
+
+    try
+    {
+        if (nNumberingLevel < 0) // It seems it's valid to omit numbering 
level, and in that case it means zero.
+            nNumberingLevel = 0;
+
+        const OUString aListName = ListDef::GetStyleName(nListId);
+        const uno::Reference< style::XStyleFamiliesSupplier > 
xStylesSupplier(GetTextDocument(), uno::UNO_QUERY_THROW);
+        const uno::Reference< container::XNameAccess > xStyleFamilies = 
xStylesSupplier->getStyleFamilies();
+        uno::Reference<container::XNameAccess> xNumberingStyles;
+        xStyleFamilies->getByName("NumberingStyles") >>= xNumberingStyles;
+        const uno::Reference<beans::XPropertySet> 
xStyle(xNumberingStyles->getByName(aListName), uno::UNO_QUERY);
+        const uno::Reference<container::XIndexAccess> 
xNumberingRules(xStyle->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
+        if (xNumberingRules.is())
+        {
+            uno::Sequence<beans::PropertyValue> aProps;
+            xNumberingRules->getByIndex(nNumberingLevel) >>= aProps;
+            for (int i = 0; i < aProps.getLength(); ++i)
+            {
+                const beans::PropertyValue& rProp = aProps[i];
+
+                if (rProp.Name == aProp)
+                {
+                    rProp.Value >>= nRet;
+                    break;
+                }
+            }
+        }
+    }
+    catch( const uno::Exception& )
+    {
+        // This can happen when the doc contains some hand-crafted invalid 
list level.
+    }
+
+    return nRet;
+}
+
 sal_Int32 DomainMapper_Impl::getCurrentNumberingProperty(const OUString& aProp)
 {
     sal_Int32 nRet = 0;
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 676ebf6e4aab..12516e8f84b6 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -892,6 +892,7 @@ public:
     */
     void processDeferredCharacterProperties();
 
+    sal_Int32 getNumberingProperty(const sal_Int32 nListId, sal_Int32 
nListLevel, const OUString& aProp);
     /// Get a property of the current numbering style's current level.
     sal_Int32 getCurrentNumberingProperty(const OUString& aProp);
 
commit bb9da1296486f6ddf9320fdec127065fbe5f04e0
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Wed Jan 17 12:03:53 2018 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:49 2020 +0200

    writerfilter: use WW8 name for StyleId
    
    The sStyleIdentifierD for the default style is "Normal".
    FindStyleSheetByISTD uses sStyleIndentifierD for its comparison.
    SetCurrentParaStyleId() is used to save the WW8 provided name.
    Thus, the default style should do the same.
    
    The SetCurrentParaStyleId was added here by
    commit 4abb20ee162ff874cc143fd952f72d30ddc9d136
    Author: Miklos Vajna
    Date:   Tue Jun 19 17:36:28 2012 +0200
    
    Also removing the static variable, since it serves no purpose.
    
    Change-Id: I58659e9d809c32dd799fb46217971707991b2803
    Reviewed-on: https://gerrit.libreoffice.org/48034
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk>
    (cherry picked from commit 9dfd46ef4b341a5dfed7d320696959402a549fdb)

diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index f2db7f4caef7..daf6d09c2179 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -3044,13 +3044,12 @@ void DomainMapper::lcl_startParagraphGroup()
     if (!(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) == 
m_pImpl->GetTopContext()))
         m_pImpl->PushProperties(CONTEXT_PARAGRAPH);
 
-    static const char sDefault[] = "Standard";
     if (m_pImpl->GetTopContext())
     {
         if (!m_pImpl->IsInShape())
         {
-            m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, 
uno::makeAny( OUString(sDefault) ) );
-            m_pImpl->SetCurrentParaStyleId(sDefault);
+            m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, 
uno::makeAny( OUString("Standard") ) ); //ConvertedStyleName
+            m_pImpl->SetCurrentParaStyleId("Normal"); //WW8 name
         }
         if (m_pImpl->isBreakDeferred(PAGE_BREAK))
             m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, 
uno::makeAny(style::BreakType_PAGE_BEFORE));
commit 626127cf0b45904778f1bfa704c4f58a4c9c4bac
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Thu Jul 12 17:15:03 2018 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:49 2020 +0200

    tdf#104354 DOCX import: fix paragraph auto spacing in tables
    
    Top margin of first paragraph of a table cell with auto spacing, and
    bottom margin of last paragraph of a table cell with auto spacing are
    zero (except in numbered last paragraphs), but LibreOffice set 14pt
    instead of them, resulting much longer tables. Following cases needed
    special handling:
    
    - auto spacing in style
    - direct top and bottom auto spacing
    - direct top and bottom margins
    - footnotes in cell paragraphs
    
    Change-Id: I462847616dd43b4ba30fae2c4eb99abb49bfb9a3
    Reviewed-on: https://gerrit.libreoffice.org/57352
    Tested-by: Jenkins
    Reviewed-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit 5c6bce38a01b21403a603acd3148cf3bbb4c685f)

diff --git a/sw/qa/extras/ooxmlexport/data/tdf104354-2.docx 
b/sw/qa/extras/ooxmlexport/data/tdf104354-2.docx
new file mode 100644
index 000000000000..9f40bf77976e
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf104354-2.docx 
differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index ee4dc2e3a71c..63638613e34d 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -1203,13 +1203,52 @@ DECLARE_OOXMLEXPORT_TEST(testTdf90789, "tdf90789.docx")
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), xPageCursor->getPage());
 }
 
-
 DECLARE_OOXMLEXPORT_TEST(testTdf90789_2, "tdf90789-2.docx")
 {
     // Section break before frame and shape was ignored
     CPPUNIT_ASSERT_EQUAL( 3, getPages() );
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf104354_2, "tdf104354-2.docx")
+{
+    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> 
xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+    uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), 
uno::UNO_QUERY);
+    uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), 
uno::UNO_QUERY);
+
+    // top margin of the first paragraph and bottom margin of the last 
paragraph
+    // is zero, when auto spacing is used.
+
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), 
"ParaTopMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), 
"ParaBottomMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), 
getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), 
"ParaTopMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), 
getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), 
"ParaBottomMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), 
getProperty<sal_Int32>(getParagraphOfText(3, xCell->getText()), 
"ParaTopMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(3, xCell->getText()), 
"ParaBottomMargin"));
+
+    // top margin is not auto spacing
+    uno::Reference<text::XTextRange> xCell2(xTable->getCellByName("A2"), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(847), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell2->getText()), 
"ParaTopMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell2->getText()), 
"ParaBottomMargin"));
+
+    // bottom margin is not auto spacing
+    uno::Reference<text::XTextRange> xCell3(xTable->getCellByName("A3"), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell3->getText()), 
"ParaTopMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(847), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell3->getText()), 
"ParaBottomMargin"));
+
+    // auto spacing, if the paragraph contains footnotes
+    uno::Reference<text::XTextRange> xCell4(xTable->getCellByName("A4"), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell4->getText()), 
"ParaTopMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell4->getText()), 
"ParaBottomMargin"));
+
+    // auto spacing on a paragraph
+    uno::Reference<text::XTextTable> xTable2(xTables->getByIndex(1), 
uno::UNO_QUERY);
+    uno::Reference<text::XTextRange> xCell5(xTable2->getCellByName("A1"), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell5->getText()), 
"ParaTopMargin"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell5->getText()), 
"ParaBottomMargin"));
+}
+
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index d868e92ee1a0..f2db7f4caef7 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -684,6 +684,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
             }
             if  (nIntValue) // If auto spacing is set, then only store set 
value in InteropGrabBag
             {
+                m_pImpl->SetParaAutoAfter(true);
                 m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN, 
uno::makeAny( ConversionHelper::convertTwipToMM100(default_spacing) ) );
             }
             else
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index eb1c2a8c5649..e33085c21ff3 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -247,7 +247,12 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_bIsSplitPara(false),
         m_vTextFramesForChaining(),
         m_bParaHadField(false),
-        m_bParaAutoBefore(false)
+        m_bParaAutoBefore(false),
+        m_bParaAutoAfter(false),
+        m_bPrevParaAutoAfter(false),
+        m_bParaChangedBottomMargin(false),
+        m_bFirstParagraphInCell(true),
+        m_bSaveFirstParagraphInCell(false)
 {
     m_aBaseUrl = rMediaDesc.getUnpackedValueOrDefault(
         utl::MediaDescriptor::PROP_DOCUMENTBASEURL(), OUString());
@@ -1068,7 +1073,6 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
 {
     if (m_bDiscardHeaderFooter)
         return;
-
 #ifdef DEBUG_WRITERFILTER
     TagLogger::getInstance().startElement("finishParagraph");
 #endif
@@ -1079,7 +1083,6 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
         return;
     TextAppendContext& rAppendContext = m_aTextAppendStack.top();
     uno::Reference< text::XTextAppend > 
xTextAppend(rAppendContext.xTextAppend);
-
 #ifdef DEBUG_WRITERFILTER
     TagLogger::getInstance().attribute("isTextAppend", 
sal_uInt32(xTextAppend.is()));
 #endif
@@ -1296,6 +1299,35 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
                     uno::Reference< text::XTextRange > xParaEnd( xCur, 
uno::UNO_QUERY );
                     CheckParaMarkerRedline( xParaEnd );
                 }
+
+                // set top margin of the previous auto paragraph in cells, 
keeping zero bottom margin only at the first one
+                if (m_nTableDepth > 0 && m_nTableDepth == m_nTableCellDepth && 
m_xPreviousParagraph.is())
+                {
+                    bool bParaChangedTopMargin = false;
+                    auto itParaTopMargin = std::find_if(aProperties.begin(), 
aProperties.end(), [](const beans::PropertyValue& rValue)
+                    {
+                        return rValue.Name == "ParaTopMargin";
+                    });
+                    if (itParaTopMargin != aProperties.end())
+                        bParaChangedTopMargin = true;
+
+                    uno::Sequence<beans::PropertyValue> aPrevPropertiesSeq;
+                    
m_xPreviousParagraph->getPropertyValue("ParaInteropGrabBag") >>= 
aPrevPropertiesSeq;
+                    auto aPrevProperties = comphelper::sequenceToContainer< 
std::vector<beans::PropertyValue> >(aPrevPropertiesSeq);
+                    auto itPrevParaAutoBefore = 
std::find_if(aPrevProperties.begin(), aPrevProperties.end(), [](const 
beans::PropertyValue& rValue)
+                    {
+                        return rValue.Name == "ParaTopMarginBeforeAutoSpacing";
+                    });
+                    bool bPrevParaAutoBefore = itPrevParaAutoBefore != 
aPrevProperties.end();
+
+                    if ((bPrevParaAutoBefore && !bParaChangedTopMargin) || 
(bParaChangedTopMargin && m_bParaAutoBefore))
+                    {
+                        sal_Int32 nSize = m_bFirstParagraphInCell ? 0 : 280;
+                        // Previous before spacing is set to auto, set 
previous before space to 280, except in the first paragraph.
+                        m_xPreviousParagraph->setPropertyValue("ParaTopMargin",
+                                 uno::makeAny( 
ConversionHelper::convertTwipToMM100(nSize)));
+                    }
+                }
             }
             if( !bKeepLastParagraphProperties )
                 rAppendContext.pLastParagraphProperties = pToBeSavedProperties;
@@ -1308,6 +1340,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
         {
             SAL_WARN( "writerfilter.dmapper", "finishParagraph() " << e );
         }
+
     }
 
     bool bIgnoreFrameState = IsInHeaderFooter();
@@ -1326,6 +1359,12 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
     if (m_bIsFirstParaInShape)
         m_bIsFirstParaInShape = false;
 
+    // keep m_bParaAutoAfter for table paragraphs
+    m_bPrevParaAutoAfter = m_bParaAutoAfter || m_bPrevParaAutoAfter;
+
+    // not auto margin in this paragraph
+    m_bParaChangedBottomMargin = (pParaContext && 
pParaContext->isSet(PROP_PARA_BOTTOM_MARGIN) && !m_bParaAutoAfter);
+
     if (pParaContext)
     {
         // Reset the frame properties for the next paragraph
@@ -1334,10 +1373,18 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap )
 
     SetIsOutsideAParagraph(true);
     m_bParaHadField = false;
+
+    // don't overwrite m_bFirstParagraphInCell in table separator nodes
+    if (m_nTableDepth > 0 && m_nTableDepth == m_nTableCellDepth)
+        m_bFirstParagraphInCell = false;
+
     m_bParaAutoBefore = false;
+    m_bParaAutoAfter = false;
+
 #ifdef DEBUG_WRITERFILTER
     TagLogger::getInstance().endElement();
 #endif
+
 }
 
 void DomainMapper_Impl::appendTextPortion( const OUString& rString, const 
PropertyMapPtr& pPropertyMap )
@@ -1731,6 +1778,7 @@ void DomainMapper_Impl::PushFootOrEndnote( bool 
bIsFootnote )
 {
     m_bInFootOrEndnote = true;
     m_bCheckFirstFootnoteTab = true;
+    m_bSaveFirstParagraphInCell = m_bFirstParagraphInCell;
     try
     {
         // Redlines outside the footnote should not affect footnote content
@@ -1898,6 +1946,7 @@ void DomainMapper_Impl::PopFootOrEndnote()
     m_aRedlines.pop();
     m_bSeenFootOrEndnoteSeparator = false;
     m_bInFootOrEndnote = false;
+    m_bFirstParagraphInCell = m_bSaveFirstParagraphInCell;
 }
 
 void DomainMapper_Impl::SeenFootOrEndnoteSeparator()
@@ -2234,9 +2283,33 @@ bool DomainMapper_Impl::IsDiscardHeaderFooter()
     return m_bDiscardHeaderFooter;
 }
 
+// called from TableManager::closeCell()
 void DomainMapper_Impl::ClearPreviousParagraph()
 {
+    // in table cells, set bottom auto margin of last paragraph to 0, except 
in paragraphs with numbering
+    if ((m_nTableDepth == (m_nTableCellDepth + 1)) && 
m_xPreviousParagraph.is() && !m_bParaChangedBottomMargin)
+    {
+        uno::Sequence<beans::PropertyValue> aPrevPropertiesSeq;
+        m_xPreviousParagraph->getPropertyValue("ParaInteropGrabBag") >>= 
aPrevPropertiesSeq;
+        auto aPrevProperties = comphelper::sequenceToContainer< 
std::vector<beans::PropertyValue> >(aPrevPropertiesSeq);
+        auto itPrevParaAutoAfter = std::find_if(aPrevProperties.begin(), 
aPrevProperties.end(), [](const beans::PropertyValue& rValue)
+        {
+            return rValue.Name == "ParaBottomMarginAfterAutoSpacing";
+        });
+        bool bPrevParaAutoAfter = itPrevParaAutoAfter != aPrevProperties.end();
+
+        bool bPrevNumberingRules = false;
+        uno::Reference<container::XNamed> 
xPreviousNumberingRules(m_xPreviousParagraph->getPropertyValue("NumberingRules"),
 uno::UNO_QUERY);
+        if (xPreviousNumberingRules.is())
+             bPrevNumberingRules = 
!xPreviousNumberingRules->getName().isEmpty();
+        if (!bPrevNumberingRules && (bPrevParaAutoAfter || 
m_bPrevParaAutoAfter))
+            m_xPreviousParagraph->setPropertyValue("ParaBottomMargin", 
uno::makeAny(static_cast<sal_Int32>(0)));
+    }
+
     m_xPreviousParagraph.clear();
+
+    // next table paragraph will be first paragraph in a cell
+    m_bFirstParagraphInCell = true;
 }
 
 static sal_Int16 lcl_ParseNumberingType( const OUString& rCommand )
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index a35d947ebe20..676ebf6e4aab 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -978,6 +978,7 @@ public:
     bool IsDiscardHeaderFooter();
 
     void SetParaAutoBefore(bool bParaAutoBefore) { m_bParaAutoBefore = 
bParaAutoBefore; }
+    void SetParaAutoAfter(bool bParaAutoAfter) { m_bParaAutoAfter = 
bParaAutoAfter; }
 
     /// Forget about the previous paragraph, as it's not inside the same
     /// start/end node.
@@ -991,6 +992,14 @@ private:
     css::uno::Reference<css::beans::XPropertySet> m_xPreviousParagraph;
     /// Current paragraph has automatic before spacing.
     bool m_bParaAutoBefore;
+    /// Current paragraph has automatic after spacing.
+    bool m_bParaAutoAfter;
+    /// Paragraph has direct top or bottom margin formattings
+    bool m_bPrevParaAutoAfter;
+    bool m_bParaChangedBottomMargin;
+    /// Current paragraph in a table is first paragraph of a cell
+    bool m_bFirstParagraphInCell;
+    bool m_bSaveFirstParagraphInCell;
 };
 
 } //namespace dmapper
commit 853480ccd1e59840053526452557ad18c7a3ef37
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Fri Mar 30 21:22:44 2018 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 18 12:36:49 2020 +0200

    tdf#106062 ooxmlimport: skip fake tab only on hanging indent
    
    Export has changed, so that it only exports a tab when the
    footnote paragraph has a hanging indent. Adjusting the import
    code to match that change.
    
    Please test with MSO before flagging this patch as a regression.
    Certainly there will be some documents previously saved by LO
    which will now, in LO, show an extra tab character after the footnote.
    Any previously saved document without a hanging indent will display
    this extra tab. However, MSO has always seen that extra tab, so
    these patches are enhancing compatibility.
    
    This patch corrects several incorrect assumptions:
    -The paragraph style is not necessarily "Footnote".
    -The paragraph may have directly defined a hanging margin.
    -An aesthetic tab is needed on a hanging indent, not a defined margin.
    
    (cherry picked from commit 946fee3ef1e319ad63a599b72dbd55ef52cbc640)
    
    Conflicts:
            sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
    
    Change-Id: Ieaa76448ce202d92efdb8d1fc04ba2674ed120ba

diff --git a/sw/qa/extras/ooxmlexport/data/tdf106062_nonHangingFootnote.odt 
b/sw/qa/extras/ooxmlexport/data/tdf106062_nonHangingFootnote.odt
new file mode 100644
index 000000000000..af5e225ea08c
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf106062_nonHangingFootnote.odt differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index 1e3b6bbfa21d..ee4dc2e3a71c 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -958,6 +958,15 @@ DECLARE_OOXMLEXPORT_TEST( testActiveXTextfield, 
"activex_textbox.docx" )
     CPPUNIT_ASSERT_EQUAL( false, getProperty<bool>(xPropertySet2, "MultiLine") 
);
 }
 

... etc. - the rest is truncated
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to