sw/qa/extras/ooxmlexport/data/tdf129575-directAfter.docx  |binary
 sw/qa/extras/ooxmlexport/data/tdf129575-directBefore.docx |binary
 sw/qa/extras/ooxmlexport/data/tdf129575-docDefault.docx   |binary
 sw/qa/extras/ooxmlexport/data/tdf129575-styleAfter.docx   |binary
 sw/qa/extras/ooxmlexport/ooxmlexport13.cxx                |    3 
 sw/qa/extras/ooxmlexport/ooxmlexport6.cxx                 |    6 -
 sw/qa/extras/ooxmlexport/ooxmlexport9.cxx                 |   65 +++++++++++
 writerfilter/source/dmapper/DomainMapperTableHandler.cxx  |   79 +++++++++-----
 writerfilter/source/dmapper/DomainMapperTableHandler.hxx  |    2 
 writerfilter/source/dmapper/DomainMapper_Impl.cxx         |   19 +++
 writerfilter/source/dmapper/DomainMapper_Impl.hxx         |    2 
 writerfilter/source/dmapper/PropertyIds.cxx               |    5 
 writerfilter/source/dmapper/PropertyIds.hxx               |    2 
 writerfilter/source/dmapper/PropertyMap.cxx               |   28 ++++
 writerfilter/source/dmapper/PropertyMap.hxx               |   19 +++
 writerfilter/source/dmapper/StyleSheetTable.cxx           |   17 +--
 writerfilter/source/dmapper/StyleSheetTable.hxx           |    1 
 17 files changed, 203 insertions(+), 45 deletions(-)

New commits:
commit f15d67442972c5f69c71925a6bfa5aa1a39d54eb
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Tue Feb 4 19:31:41 2020 +0100
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Wed Feb 12 14:16:30 2020 +0100

    tdf#129575 DOCX import: fix table style preference
    
    handling by recognizing docDefault properties
    instead of default-value based heuristics.
    
    Change-Id: I3bab9d85d77d0e5f1c357121b1caf02cbe4899c4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88457
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf129575-directAfter.docx 
b/sw/qa/extras/ooxmlexport/data/tdf129575-directAfter.docx
new file mode 100644
index 000000000000..c9856b02857b
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf129575-directAfter.docx differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf129575-directBefore.docx 
b/sw/qa/extras/ooxmlexport/data/tdf129575-directBefore.docx
new file mode 100644
index 000000000000..5e75ef1be5d2
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf129575-directBefore.docx differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf129575-docDefault.docx 
b/sw/qa/extras/ooxmlexport/data/tdf129575-docDefault.docx
new file mode 100644
index 000000000000..d7cdf2ec4308
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf129575-docDefault.docx differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf129575-styleAfter.docx 
b/sw/qa/extras/ooxmlexport/data/tdf129575-styleAfter.docx
new file mode 100644
index 000000000000..97439011ff55
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf129575-styleAfter.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index 550255d54e8a..27c66c141357 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -325,8 +325,6 @@ DECLARE_OOXMLEXPORT_TEST(testTdf123636_newlinePageBreak4, 
"tdf123636_newlinePage
     assertXPath(pDump, "/root/page[2]/body/txt[1]/Text", 0);
 }
 
-// disabled temporarily, next commit enables it again
-#if 0
 DECLARE_OOXMLEXPORT_TEST(testTdf118947_tableStyle, "tdf118947_tableStyle.docx")
 {
     uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), 
uno::UNO_QUERY);
@@ -354,7 +352,6 @@ DECLARE_OOXMLEXPORT_TEST(testTdf118947_tableStyle, 
"tdf118947_tableStyle.docx")
     CPPUNIT_ASSERT_EQUAL_MESSAGE("Table style sets 0 right margin", 
sal_Int32(0), getProperty<sal_Int32>(xPara, "ParaRightMargin"));
     CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table sets 2.5 line-spacing", 
sal_Int16(250), getProperty<style::LineSpacing>(xPara, 
"ParaLineSpacing").Height, 1);
 }
-#endif
 
 DECLARE_OOXMLEXPORT_TEST(tdf123912_protectedForm, 
"tdf123912_protectedForm.odt")
 {
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
index 3b5726dceb28..45bcc9ac5f27 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
@@ -459,9 +459,9 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf128752, 
"tdf128752.docx")
 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf119054, "tdf119054.docx")
 {
     xmlDocPtr pXmlDoc = parseExport();
-    // Don't overwrite before and after spacing of Heading2 by table style
-    assertXPathNoAttribute(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p[1]/w:pPr/w:spacing", "before");
-    assertXPathNoAttribute(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p[1]/w:pPr/w:spacing", "after");
+    // Overwrite applied table style with before and after spacing of Heading2
+    assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p[1]/w:pPr/w:spacing", "before", 
"0");
+    assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p[1]/w:pPr/w:spacing", "after", 
"360");
     // Use table style based single line spacing instead of the docDefaults' 
254
     assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p[1]/w:pPr/w:spacing", "line", 
"240");
 }
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index 149b5dc3e3cd..df96f077389a 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -30,6 +30,7 @@
 #include <com/sun/star/view/XSelectionSupplier.hpp>
 #include <com/sun/star/style/LineSpacing.hpp>
 #include <com/sun/star/style/LineSpacingMode.hpp>
+//#include <com/sun/star/drawing/LineStyle.hpp>
 #include <com/sun/star/style/ParagraphAdjust.hpp>
 #include <com/sun/star/drawing/XControlShape.hpp>
 #include <com/sun/star/text/TextContentAnchorType.hpp>
@@ -184,6 +185,70 @@ DECLARE_OOXMLEXPORT_TEST(testTdf106690Cell, 
"tdf106690-cell.docx")
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), 
getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), 
"ParaBottomMargin"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf129575_directBefore, 
"tdf129575-directBefore.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);
+    // direct paragraph formatting
+    // This was 212 twips from the table style, but always direct paragraph 
formatting wins, in the case of the default 0 margin, too
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), 
"ParaTopMargin"));
+    // default margin
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), 
"ParaBottomMargin"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf129575_directAfter, 
"tdf129575-directAfter.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);
+    // from table style
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(212), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), 
"ParaTopMargin"));
+    // direct paragraph formatting
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), 
"ParaBottomMargin"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf129575_styleAfter, "tdf129575-styleAfter.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);
+    // direct paragraph formatting
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), 
"ParaTopMargin"));
+    // from table style
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(212), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), 
"ParaBottomMargin"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf129575_docDefault, "tdf129575-docDefault.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);
+    // docDefault defines both bottom margin and line spacing, but
+    // applied bottom margin values are based on non-docDefault paragraph 
styles, line spacing is based on table style
+
+    // docDefault: <w:spacing w:after="160" w:line="320" w:lineRule="auto"/>
+    // table style: <w:spacing w:after="0" w:line="240" w:lineRule="auto"/> 
(single line space, overwriting bigger docDefault)
+
+    // Paragraph style Normal: <w:spacing w:after="160"/> (same as docDefault),
+    // table style based single line spacing
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(282), 
getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), 
"ParaBottomMargin"));
+    style::LineSpacing aLineSpacing = 
getProperty<style::LineSpacing>(getParagraphOfText(1, xCell->getText()), 
"ParaLineSpacing");
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::PROP), 
aLineSpacing.Mode);
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(100), aLineSpacing.Height);
+    // Heading 2: <w:spacing w:after="360"/> (different from docDefault),
+    // table style based single line spacing
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(635), 
getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), 
"ParaBottomMargin"));
+    aLineSpacing = getProperty<style::LineSpacing>(getParagraphOfText(1, 
xCell->getText()), "ParaLineSpacing");
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::PROP), 
aLineSpacing.Mode);
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(100), aLineSpacing.Height);
+
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf106970, "tdf106970.docx")
 {
     // The second paragraph (first numbered one) had 0 bottom margin:
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx 
b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index e753852985a7..ab51d4fdd48d 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -59,6 +59,7 @@ using namespace ::std;
 #define CNF_FIRST_ROW_FIRST_COLUMN  0x004
 #define CNF_LAST_ROW_LAST_COLUMN    0x002
 #define CNF_LAST_ROW_FIRST_COLUMN   0x001
+#define CNF_ALL                     0xFFF
 
 DomainMapperTableHandler::DomainMapperTableHandler(
             css::uno::Reference<css::text::XTextAppendAndConvert> const& xText,
@@ -225,6 +226,7 @@ struct TableInfo
     PropertyMapPtr pTableBorders;
     TableStyleSheetEntry* pTableStyle;
     css::beans::PropertyValues aTableProperties;
+    std::vector< PropertyIds > aTablePropertyIds;
 
     TableInfo()
     : nLeftBorderDistance(DEF_BORDER_DIST)
@@ -664,6 +666,7 @@ TableStyleSheetEntry * 
DomainMapperTableHandler::endTableGetTableStyle(TableInfo
         }
 
         rInfo.aTableProperties = m_aTableProperties->GetPropertyValues();
+        rInfo.aTablePropertyIds = m_aTableProperties->GetPropertyIds();
 
 #ifdef DBG_UTIL
         TagLogger::getInstance().startElement("debug.tableprops");
@@ -863,9 +866,6 @@ CellPropertyValuesSeq_t 
DomainMapperTableHandler::endTableGetCellProperties(Tabl
                 // Remove properties from style/row that aren't allowed in 
cells
                 pAllCellProps->Erase( PROP_HEADER_ROW_COUNT );
                 pAllCellProps->Erase( PROP_TBL_HEADER );
-                // Remove paragraph properties from style/row that paragraph 
style can overwrite
-                pAllCellProps->Erase( PROP_PARA_BOTTOM_MARGIN );
-                pAllCellProps->Erase( PROP_PARA_LINE_SPACING );
 
                 // Then add the cell properties
                 pAllCellProps->InsertProps(*aCellIterator);
@@ -1066,29 +1066,59 @@ css::uno::Sequence<css::beans::PropertyValues> 
DomainMapperTableHandler::endTabl
 
 // table style has got bigger precedence than docDefault style,
 // but lower precedence than the paragraph styles and direct paragraph 
formatting
-void DomainMapperTableHandler::ApplyParaProperty(css::beans::PropertyValues 
aTableProperties, PropertyIds eId)
+void 
DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle(TableInfo & 
rInfo)
 {
-    OUString sPropertyName = getPropertyName(eId);
-    auto pTableProp = std::find_if(aTableProperties.begin(), 
aTableProperties.end(),
-        [&](const beans::PropertyValue& rProp) { return rProp.Name == 
sPropertyName; });
-    if (pTableProp != aTableProperties.end())
+    for( auto const& eId : rInfo.aTablePropertyIds )
     {
-        uno::Any aValue = pTableProp->Value;
-        for (const auto& rParaProp : m_rDMapper_Impl.m_aParagraphsToEndTable)
+        // apply paragraph and character properties of the table style on 
table paragraphs
+        if ( isParagraphProperty(eId) || isCharacterProperty(eId) )
         {
-            // there is no direct paragraph formatting
-            if (!rParaProp.m_pPropertyMap->isSet(eId))
+            // check all paragraphs of the table
+            for (const auto& rParaProp : 
m_rDMapper_Impl.m_aParagraphsToEndTable)
             {
-                OUString sParaStyleName;
-                rParaProp.m_rPropertySet->getPropertyValue("ParaStyleName") 
>>= sParaStyleName;
-                StyleSheetEntryPtr pEntry = 
m_rDMapper_Impl.GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(sParaStyleName);
-                uno::Any aMargin = 
m_rDMapper_Impl.GetPropertyFromStyleSheet(eId, pEntry, true, true);
-                uno::Any aMarginDocDefault = 
m_rDMapper_Impl.GetPropertyFromStyleSheet(eId, nullptr, true, true);
-                // use table style only when 1) both values are empty (no 
docDefault and paragraph style definitions) or
-                // 2) both non-empty values are equal (docDefault paragraph 
properties are copied to the base paragraph style during import)
-                // TODO check the case, when two parent styles modify the 
docDefault and the last one set back the docDefault value
-                if (aMargin == aMarginDocDefault)
-                    rParaProp.m_rPropertySet->setPropertyValue(sPropertyName, 
aValue);
+                // there is no direct paragraph formatting
+                if (!rParaProp.m_pPropertyMap->isSet(eId))
+                {
+                    bool bDocDefault;
+                    OUString sParaStyleName;
+                    
rParaProp.m_rPropertySet->getPropertyValue("ParaStyleName") >>= sParaStyleName;
+                    StyleSheetEntryPtr pEntry = 
m_rDMapper_Impl.GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(sParaStyleName);
+                    uno::Any aParaStyle = 
m_rDMapper_Impl.GetPropertyFromStyleSheet(eId, pEntry, true, true, 
&bDocDefault);
+                    // use table style when a docDefault value is applied 
instead of it,
+                    // and there is no associated TableStyleSheetEntry
+                    // TODO: replace CNF_ALL with the actual mask
+                    if ( (aParaStyle == uno::Any() || bDocDefault) && 
!rInfo.pTableStyle->GetProperties(CNF_ALL)->getProperty(eId) )
+                    {
+                        OUString sPropertyName = getPropertyName(eId);
+                        auto pTableProp = 
std::find_if(rInfo.aTableProperties.begin(), rInfo.aTableProperties.end(),
+                            [&](const beans::PropertyValue& rProp) { return 
rProp.Name == sPropertyName; });
+                        if (pTableProp != rInfo.aTableProperties.end())
+                        {
+                            try
+                            {
+                                rParaProp.m_rPropertySet->setPropertyValue( 
sPropertyName, pTableProp->Value );
+                            }
+                            catch ( const uno::Exception & )
+                            {
+                                TOOLS_INFO_EXCEPTION("writerfilter.dmapper", 
"Exception during table style correction");
+                            }
+                        }
+                    }
+                    // table style can overwrite paragraph style, when the 
paragraph style property has a default value, restore it
+                    // TODO remove the associated TableStyleSheetEntry styles, 
if needed
+                    else if ( aParaStyle != uno::Any() && !bDocDefault )
+                    {
+                        OUString sPropertyName = getPropertyName(eId);
+                        try
+                        {
+                            rParaProp.m_rPropertySet->setPropertyValue( 
sPropertyName, aParaStyle );
+                        }
+                        catch ( const uno::Exception & )
+                        {
+                            TOOLS_INFO_EXCEPTION("writerfilter.dmapper", 
"Exception during table style correction");
+                        }
+                    }
+                }
             }
         }
     }
@@ -1192,9 +1222,8 @@ void DomainMapperTableHandler::endTable(unsigned int 
nestedTableLevel, bool bTab
                     }
                 }
 
-                // OOXML table style may container paragraph properties, apply 
these now.
-                ApplyParaProperty(aTableInfo.aTableProperties, 
PROP_PARA_BOTTOM_MARGIN);
-                ApplyParaProperty(aTableInfo.aTableProperties, 
PROP_PARA_LINE_SPACING);
+                // OOXML table style may contain paragraph properties, apply 
these now.
+                ApplyParagraphPropertiesFromTableStyle(aTableInfo);
             }
         }
         catch ( const lang::IllegalArgumentException & )
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx 
b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
index 16d2a0cc37cc..b454be94f563 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
@@ -91,7 +91,7 @@ public:
      */
     void startTable(const TablePropertyMapPtr& pProps);
 
-    void ApplyParaProperty(css::beans::PropertyValues aTableProperties, 
PropertyIds eId);
+    void ApplyParagraphPropertiesFromTableStyle(TableInfo & rInfo);
 
     /// Handle end of table.
     void endTable(unsigned int nestedTableLevel, bool bTableStartsAtCellStart);
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 2f3e79ec852e..259e1ebbf678 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -807,7 +807,7 @@ OUString DomainMapper_Impl::GetDefaultParaStyleName()
     return m_sDefaultParaStyleName;
 }
 
-uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, 
StyleSheetEntryPtr pEntry, const bool bDocDefaults, const bool bPara)
+uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, 
StyleSheetEntryPtr pEntry, const bool bDocDefaults, const bool bPara, bool* 
pIsDocDefault)
 {
     while(pEntry.get( ) )
     {
@@ -817,6 +817,9 @@ uno::Any 
DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, StyleShee
                     pEntry->pProperties->getProperty(eId);
             if( aProperty )
             {
+                if (pIsDocDefault)
+                    *pIsDocDefault = pEntry->pProperties->isDocDefault(eId);
+
                 return aProperty->second;
             }
         }
@@ -840,7 +843,12 @@ uno::Any 
DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, StyleShee
         {
             o3tl::optional<PropertyMap::Property> aProperty = 
pDefaultParaProps->getProperty(eId);
             if ( aProperty )
+            {
+                if (pIsDocDefault)
+                    *pIsDocDefault = true;
+
                 return aProperty->second;
+            }
         }
     }
     if ( bDocDefaults && isCharacterProperty(eId) )
@@ -850,9 +858,18 @@ uno::Any 
DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, StyleShee
         {
             o3tl::optional<PropertyMap::Property> aProperty = 
pDefaultCharProps->getProperty(eId);
             if ( aProperty )
+            {
+                if (pIsDocDefault)
+                    *pIsDocDefault = true;
+
                 return aProperty->second;
+            }
         }
     }
+
+    if (pIsDocDefault)
+        *pIsDocDefault = false;
+
     return uno::Any();
 }
 
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index bc688a463cd7..0fd51ab2298e 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -761,7 +761,7 @@ public:
     OUString  GetDefaultParaStyleName();
 
     // specified style - including inherited properties. Indicate whether 
paragraph defaults should be checked.
-    css::uno::Any GetPropertyFromStyleSheet(PropertyIds eId, 
StyleSheetEntryPtr pEntry, const bool bDocDefaults, const bool bPara);
+    css::uno::Any GetPropertyFromStyleSheet(PropertyIds eId, 
StyleSheetEntryPtr pEntry, const bool bDocDefaults, const bool bPara, bool* 
bIsDocDefault = nullptr);
     // current paragraph style - including inherited properties
     css::uno::Any GetPropertyFromParaStyleSheet(PropertyIds eId);
     // context's character style - including inherited properties
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx 
b/writerfilter/source/dmapper/PropertyIds.cxx
index 8b925fe37f9f..bb133dff2f7a 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -364,6 +364,11 @@ bool isCharacterProperty( const PropertyIds eId )
     return eId > PROP_CHARACTER_STYLES && eId < PROP_CHARACTER_END;
 }
 
+bool isParagraphProperty( const PropertyIds eId )
+{
+    return eId >= PROP_PARA_ADJUST && eId <= PROP_PARA_WIDOWS;
+}
+
 } //namespace writerfilter
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx 
b/writerfilter/source/dmapper/PropertyIds.hxx
index b2e10a13ee46..ce238f340a59 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -362,6 +362,8 @@ OUString getPropertyName(PropertyIds eId);
 
 bool isCharacterProperty(const PropertyIds eId);
 
+bool isParagraphProperty(const PropertyIds eId);
+
 } //namespace dmapper
 } // namespace writerfilter
 #endif
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx 
b/writerfilter/source/dmapper/PropertyMap.cxx
index 69cc86a73153..b15e17696a78 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -185,6 +185,14 @@ uno::Sequence< beans::PropertyValue > 
PropertyMap::GetPropertyValues( bool bChar
     return comphelper::containerToSequence( m_aValues );
 }
 
+std::vector< PropertyIds > PropertyMap::GetPropertyIds()
+{
+    std::vector< PropertyIds > aRet;
+    for ( const auto& rPropPair : m_vMap )
+        aRet.push_back( rPropPair.first );
+    return aRet;
+}
+
 #ifdef DBG_UTIL
 static void lcl_AnyToTag( const uno::Any& rAny )
 {
@@ -223,7 +231,7 @@ static void lcl_AnyToTag( const uno::Any& rAny )
 }
 #endif
 
-void PropertyMap::Insert( PropertyIds eId, const uno::Any& rAny, bool 
bOverwrite, GrabBagType i_GrabBagType )
+void PropertyMap::Insert( PropertyIds eId, const uno::Any& rAny, bool 
bOverwrite, GrabBagType i_GrabBagType, bool bDocDefault )
 {
 #ifdef DBG_UTIL
     const OUString& rInsert = getPropertyName(eId);
@@ -235,7 +243,7 @@ void PropertyMap::Insert( PropertyIds eId, const uno::Any& 
rAny, bool bOverwrite
 #endif
 
     if ( !bOverwrite )
-        m_vMap.insert(std::make_pair(eId, PropValue(rAny, i_GrabBagType)));
+        m_vMap.insert(std::make_pair(eId, PropValue(rAny, i_GrabBagType, 
bDocDefault)));
     else
         m_vMap[eId] = PropValue(rAny, i_GrabBagType);
 
@@ -264,6 +272,15 @@ bool PropertyMap::isSet( PropertyIds eId) const
     return m_vMap.find( eId ) != m_vMap.end();
 }
 
+bool PropertyMap::isDocDefault( PropertyIds eId ) const
+{
+    std::map< PropertyIds, PropValue >::const_iterator aIter = m_vMap.find( 
eId );
+    if ( aIter == m_vMap.end() )
+        return false;
+    else
+        return aIter->second.getIsDocDefault();
+}
+
 #ifdef DBG_UTIL
 void PropertyMap::dumpXml() const
 {
@@ -320,7 +337,12 @@ void PropertyMap::InsertProps( const PropertyMapPtr& rMap, 
const bool bOverwrite
         for ( const auto& rPropPair : rMap->m_vMap )
         {
             if ( bOverwrite || !m_vMap.count(rPropPair.first) )
-                m_vMap[rPropPair.first] = rPropPair.second;
+            {
+                if ( !bOverwrite && !rPropPair.second.getIsDocDefault() )
+                    m_vMap.insert(std::make_pair(rPropPair.first, 
PropValue(rPropPair.second.getValue(), rPropPair.second.getGrabBagType(), 
true)));
+                else
+                    m_vMap[rPropPair.first] = rPropPair.second;
+            }
         }
 
         insertTableProperties( rMap.get(), bOverwrite );
diff --git a/writerfilter/source/dmapper/PropertyMap.hxx 
b/writerfilter/source/dmapper/PropertyMap.hxx
index b7603301ccc8..11df0d8fad9c 100644
--- a/writerfilter/source/dmapper/PropertyMap.hxx
+++ b/writerfilter/source/dmapper/PropertyMap.hxx
@@ -95,23 +95,35 @@ class PropValue
 private:
     css::uno::Any m_aValue;
     GrabBagType   m_GrabBagType;
+    bool          m_bIsDocDefault;
 
 public:
+    PropValue( const css::uno::Any& rValue, GrabBagType i_GrabBagType, bool 
bDocDefault )
+        : m_aValue( rValue )
+        , m_GrabBagType( i_GrabBagType )
+        , m_bIsDocDefault( bDocDefault )
+    {
+    }
+
     PropValue( const css::uno::Any& rValue, GrabBagType i_GrabBagType )
         : m_aValue( rValue )
         , m_GrabBagType( i_GrabBagType )
+        , m_bIsDocDefault( false )
     {
     }
 
     PropValue()
         : m_aValue()
         , m_GrabBagType( NO_GRAB_BAG )
+        , m_bIsDocDefault( false )
     {
     }
 
     const css::uno::Any& getValue() const { return m_aValue; }
 
     GrabBagType getGrabBagType() const { return m_GrabBagType; }
+
+    bool getIsDocDefault() const { return m_bIsDocDefault; }
 };
 
 class PropertyMap;
@@ -139,13 +151,15 @@ public:
     // the contained properties are their Value.
     css::uno::Sequence< css::beans::PropertyValue > GetPropertyValues( bool 
bCharGrabBag = true );
 
+    std::vector< PropertyIds > GetPropertyIds();
+
     // Add property, optionally overwriting existing attributes
-    void Insert( PropertyIds eId, const css::uno::Any& rAny, bool bOverwrite = 
true, GrabBagType i_GrabBagType = NO_GRAB_BAG );
+    void Insert( PropertyIds eId, const css::uno::Any& rAny, bool bOverwrite = 
true, GrabBagType i_GrabBagType = NO_GRAB_BAG, bool bDocDefault = false );
 
     // Remove a named property from *this, does nothing if the property id has 
not been set
     void Erase( PropertyIds eId);
 
-    // Imports properties from pMap
+    // Imports properties from pMap (bOverwrite==false means 
m_bIsDocDefault=true setting)
     void InsertProps( const PropertyMapPtr& rMap, const bool bOverwrite = true 
);
 
     // Returns a copy of the property if it exists, .first is its PropertyIds 
and .second is its Value (type css::uno::Any)
@@ -153,6 +167,7 @@ public:
 
     // Has the property named been set (via Insert)?
     bool isSet( PropertyIds eId ) const;
+    bool isDocDefault( PropertyIds eId ) const;
 
     const css::uno::Reference< css::text::XFootnote >& GetFootnote() const { 
return m_xFootnote; }
     const OUString& GetFootnoteStyle() const { return 
m_sFootnoteCharStyleName; }
diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx 
b/writerfilter/source/dmapper/StyleSheetTable.cxx
index bf3fb63664ed..33c22e357110 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.cxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.cxx
@@ -396,6 +396,11 @@ StyleSheetTable::~StyleSheetTable()
 {
 }
 
+void StyleSheetTable::SetDefaultParaProps(PropertyIds eId, const 
css::uno::Any& rAny)
+{
+    m_pImpl->m_pDefaultParaProps->Insert(eId, rAny, /*bOverwrite=*/false, 
NO_GRAB_BAG, /*bDocDefault=*/true);
+}
+
 PropertyMapPtr const & StyleSheetTable::GetDefaultParaProps() const
 {
     return m_pImpl->m_pDefaultParaProps;
@@ -691,7 +696,7 @@ void StyleSheetTable::lcl_sprm(Sprm & rSprm)
             if ( nSprmId == NS_ooxml::LN_CT_DocDefaults_pPrDefault && 
m_pImpl->m_pDefaultParaProps.get() &&
                 !m_pImpl->m_pDefaultParaProps->isSet( PROP_PARA_TOP_MARGIN ) )
             {
-                m_pImpl->m_pDefaultParaProps->Insert( PROP_PARA_TOP_MARGIN, 
uno::makeAny( sal_Int32(0) ) );
+                SetDefaultParaProps( PROP_PARA_TOP_MARGIN, uno::makeAny( 
sal_Int32(0) ) );
             }
             m_pImpl->m_rDMapper.PopStyleSheetProperties();
             applyDefaults( true );
@@ -990,7 +995,7 @@ void StyleSheetTable::ApplyStyleSheets( const FontTablePtr& 
rFontTable )
                     else if( bParaStyle )
                     {
                         // Paragraph styles that don't inherit from some 
parent need to apply the DocDefaults
-                        pEntry->pProperties->InsertProps( 
m_pImpl->m_pDefaultParaProps, /*bAllowOverwrite=*/false );
+                        pEntry->pProperties->InsertProps( 
m_pImpl->m_pDefaultParaProps, /*bOverwrite=*/false );
 
                         //now it's time to set the default parameters - for 
paragraph styles
                         //Fonts: Western first entry in font table
@@ -1454,13 +1459,13 @@ void StyleSheetTable::applyDefaults(bool 
bParaProperties)
         if( bParaProperties && m_pImpl->m_pDefaultParaProps.get())
         {
             // tdf#87533 LO will have different defaults here, depending on 
the locale. Import with documented defaults
-            m_pImpl->m_pDefaultParaProps->Insert(PROP_WRITING_MODE, 
uno::makeAny(sal_Int16(text::WritingMode_LR_TB)), /*bOverwrite=*/false);
-            m_pImpl->m_pDefaultParaProps->Insert(PROP_PARA_ADJUST, 
uno::makeAny(sal_Int16(style::ParagraphAdjust_LEFT)), false);
+            SetDefaultParaProps(PROP_WRITING_MODE, 
uno::makeAny(sal_Int16(text::WritingMode_LR_TB)));
+            SetDefaultParaProps(PROP_PARA_ADJUST, 
uno::makeAny(sal_Int16(style::ParagraphAdjust_LEFT)));
 
             // Widow/Orphan -> set both to two if not already set
             uno::Any aTwo = uno::makeAny(sal_Int8(2));
-            m_pImpl->m_pDefaultParaProps->Insert(PROP_PARA_WIDOWS, aTwo, 
/*bOverwrite=*/false);
-            m_pImpl->m_pDefaultParaProps->Insert(PROP_PARA_ORPHANS, aTwo, 
false);
+            SetDefaultParaProps(PROP_PARA_WIDOWS, aTwo);
+            SetDefaultParaProps(PROP_PARA_ORPHANS, aTwo);
 
             uno::Reference<style::XStyleFamiliesSupplier> 
xStylesSupplier(m_pImpl->m_xTextDocument, uno::UNO_QUERY);
             uno::Reference<container::XNameAccess> xStyleFamilies = 
xStylesSupplier->getStyleFamilies();
diff --git a/writerfilter/source/dmapper/StyleSheetTable.hxx 
b/writerfilter/source/dmapper/StyleSheetTable.hxx
index 0866852c36e6..0d367de59f52 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.hxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.hxx
@@ -102,6 +102,7 @@ public:
 
     OUString getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, 
bool bAlwaysCreate );
 
+    void SetDefaultParaProps(PropertyIds eId, const css::uno::Any& rAny);
     PropertyMapPtr const & GetDefaultParaProps() const;
     /// Returns the default character properties.
     PropertyMapPtr const & GetDefaultCharProps() const;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to