bnc#816593 DOCX filter: import paragraph spacing from table style

Change-Id: I9dce59ecd8a2d2bfadb8c7273cd46c6c0cf17774
diff --git a/sw/qa/extras/ooxmlimport/data/table-style-parprop.docx b/sw/qa/extras/ooxmlimport/data/table-style-parprop.docx
new file mode 100755
index 0000000..1c68c70
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/table-style-parprop.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 3c13f05..64c0764 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -128,6 +128,7 @@ public:
    void testGroupshapeRotation();
    void testBnc780044Spacing();
    void testTableAutoNested();
    void testTableStyleParprop();

    CPPUNIT_TEST_SUITE(Test);
#if !defined(MACOSX) && !defined(WNT)
@@ -222,6 +223,7 @@ void Test::run()
        {"groupshape-rotation.docx", &Test::testGroupshapeRotation},
        {"bnc780044_spacing.docx", &Test::testBnc780044Spacing},
        {"table-auto-nested.docx", &Test::testTableAutoNested},
        {"table-style-parprop.docx", &Test::testTableStyleParprop},
    };
    header();
    for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -1508,6 +1510,15 @@ void Test::testTableAutoNested()
    CPPUNIT_ASSERT_EQUAL(sal_Int32(23051), getProperty<sal_Int32>(xTables->getByIndex(1), "Width"));
}

void Test::testTableStyleParprop()
{
    // The problem was that w:spacing's w:after=0 (a paragraph property) wasn't imported from table style.
    uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
    uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
    // This was 353, the document default, i.e. paragraph property from table style had no effect.
    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
}

CPPUNIT_TEST_SUITE_REGISTRATION(Test);

CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index 3d99fa2..250ea42 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -19,9 +19,12 @@
#include <DomainMapperTableHandler.hxx>
#include <DomainMapper_Impl.hxx>
#include <StyleSheetTable.hxx>
#include <com/sun/star/beans/XPropertyState.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/table/TableBorderDistances.hpp>
#include <com/sun/star/table/TableBorder.hpp>
#include <com/sun/star/table/BorderLine2.hpp>
#include <com/sun/star/table/XCellRange.hpp>
#include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/RelOrientation.hpp>
#include <com/sun/star/text/SizeType.hpp>
@@ -779,6 +782,22 @@ RowPropertyValuesSeq_t DomainMapperTableHandler::endTableGetRowProperties()
    return aRowProperties;
}

// Apply paragraph property to each paragraph within a cell.
static void lcl_ApplyCellParaProps(uno::Reference<table::XCell> xCell, uno::Any aBottomMargin)
{
    uno::Reference<container::XEnumerationAccess> xEnumerationAccess(xCell, uno::UNO_QUERY);
    uno::Reference<container::XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration();
    while (xEnumeration->hasMoreElements())
    {
        uno::Reference<beans::XPropertySet> xParagraph(xEnumeration->nextElement(), uno::UNO_QUERY);
        uno::Reference<beans::XPropertyState> xPropertyState(xParagraph, uno::UNO_QUERY);
        // Don't apply in case direct formatting is already present.
        // TODO: probably paragraph style has priority over table style here.
        if (xPropertyState.is() && xPropertyState->getPropertyState("ParaBottomMargin") == beans::PropertyState_DEFAULT_VALUE)
            xParagraph->setPropertyValue("ParaBottomMargin", aBottomMargin);
    }
}

void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
{
#ifdef DEBUG_DMAPPER_TABLE_HANDLER
@@ -825,6 +844,25 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)

                if (xTable.is())
                    m_xTableRange = xTable->getAnchor( );

                // OOXML table style may container paragraph properties, apply these now.
                for (int i = 0; i < aTableInfo.aTableProperties.getLength(); ++i)
                {
                    if (aTableInfo.aTableProperties[i].Name == "ParaBottomMargin")
                    {
                        uno::Reference<table::XCellRange> xCellRange(xTable, uno::UNO_QUERY);
                        uno::Any aBottomMargin = aTableInfo.aTableProperties[i].Value;
                        sal_Int32 nRows = aCellProperties.getLength();
                        for (sal_Int32 nRow = 0; nRow < nRows; ++nRow)
                        {
                            const uno::Sequence< beans::PropertyValues > aCurrentRow = aCellProperties[nRow];
                            sal_Int32 nCells = aCurrentRow.getLength();
                            for (sal_Int32 nCell = 0; nCell < nCells; ++nCell)
                                lcl_ApplyCellParaProps(xCellRange->getCellByPosition(nCell, nRow), aBottomMargin);
                        }
                        break;
                    }
                }
            }
        }
        catch ( const lang::IllegalArgumentException &e )