DOCX import: fixed horizontal position of floating tables

In Word, just like normal tables, floating tables should be positioned
in a way that the start of the cell text has the same horizontal
position as normal paragraph text.

To emulate this, first the table should be moved left by the table
border distance, then also by the border with / 2; as done for
non-floating tables already.

Change-Id: I581311fbb08009e6c1839106e8f615d078a4a705
diff --git a/sw/qa/extras/ooxmlimport/data/table-floating.docx b/sw/qa/extras/ooxmlimport/data/table-floating.docx
new file mode 100755
index 0000000..1e0cb30
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/table-floating.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index f9d3416..c85b288 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -128,6 +128,7 @@ public:
    void testFdo66474();
    void testGroupshapeRotation();
    void testBnc780044Spacing();
    void testTableFloating();

    CPPUNIT_TEST_SUITE(Test);
#if !defined(MACOSX) && !defined(WNT)
@@ -221,6 +222,7 @@ void Test::run()
        {"fdo66474.docx", &Test::testFdo66474},
        {"groupshape-rotation.docx", &Test::testGroupshapeRotation},
        {"bnc780044_spacing.docx", &Test::testBnc780044Spacing},
        {"table-floating.docx", &Test::testTableFloating},
    };
    header();
    for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -1550,6 +1552,23 @@ void Test::testBnc780044Spacing()
    CPPUNIT_ASSERT_EQUAL(sal_Int16(1), xCursor->getPage());
}

void Test::testTableFloating()
{
    // Both the size and the position of the table was incorrect.
    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
    // Second table was too wide: 16249, i.e. as wide as the first table.
    CPPUNIT_ASSERT_EQUAL(sal_Int32(11248), getProperty<sal_Int32>(xTables->getByIndex(1), "Width"));

    uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
    uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    // This was 0, should be the the opposite of (left margin + half of the border width).
    CPPUNIT_ASSERT_EQUAL(sal_Int32(-199), getProperty<sal_Int32>(xFrame, "HoriOrientPosition"));
    // Was 0 as well, should be the right margin.
    CPPUNIT_ASSERT_EQUAL(sal_Int32(191), getProperty<sal_Int32>(xFrame, "RightMargin"));
}

CPPUNIT_TEST_SUITE_REGISTRATION(Test);

CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index 3d695fe..72d7c74 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -38,8 +38,6 @@ namespace dmapper {
using namespace ::com::sun::star;
using namespace ::std;

#define DEF_BORDER_DIST 190  //0,19cm

#ifdef DEBUG_DMAPPER_TABLE_HANDLER
static void  lcl_printProperties( PropertyMapPtr pProps )
{
@@ -308,7 +306,7 @@ bool lcl_extractTableBorderProperty(PropertyMapPtr pTableProperties, const Prope

}

TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo)
TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo, uno::Sequence<beans::PropertyValue>& rFrameProperties)
{
    // will receive the table style if any
    TableStyleSheetEntry* pTableStyle = NULL;
@@ -428,7 +426,25 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo
            aTableBorder.IsLeftLineValid = sal_True;
            // Only top level table position depends on border width
            if (rInfo.nNestLevel == 1)
                rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5;
            {
                if (!rFrameProperties.hasElements())
                    rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5;
                else
                {
                    // If this is a floating table, then the position of the frame should be adjusted, instead.
                    for (sal_Int32 i = 0; i < rFrameProperties.getLength(); ++i)
                    {
                        beans::PropertyValue& rPropertyValue = rFrameProperties[i];
                        if (rPropertyValue.Name == "HoriOrientPosition")
                        {
                            sal_Int32 nValue = rPropertyValue.Value.get<sal_Int32>();
                            nValue -= aLeftBorder.LineWidth * 0.5;
                            rPropertyValue.Value <<= nValue;
                            break;
                        }
                    }
                }
            }
        }
        if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_RIGHT_BORDER, rInfo, aBorderLine))
        {
@@ -762,9 +778,11 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
    dmapper_logger->startElement("tablehandler.endTable");
#endif

    // If we want to make this table a floating one.
    uno::Sequence<beans::PropertyValue> aFrameProperties = m_rDMapper_Impl.getTableManager().getCurrentTablePosition();
    TableInfo aTableInfo;
    aTableInfo.nNestLevel = nestedTableLevel;
    aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo);
    aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo, aFrameProperties);
    //  expands to uno::Sequence< Sequence< beans::PropertyValues > >

    CellPropertyValuesSeq_t aCellProperties = endTableGetCellProperties(aTableInfo);
@@ -779,8 +797,6 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
    {
        uno::Reference<text::XTextRange> xStart;
        uno::Reference<text::XTextRange> xEnd;
        // If we want to make this table a floating one.
        uno::Sequence<beans::PropertyValue> aFrameProperties = m_rDMapper_Impl.getTableManager().getCurrentTablePosition();
        bool bFloating = aFrameProperties.hasElements();
        // Additional checks: if we can do this.
        if (bFloating && (*m_pTableSeq)[0].getLength() > 0 && (*m_pTableSeq)[0][0].getLength() > 0)
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
index ea4c421..792b978 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
@@ -45,6 +45,8 @@ typedef ::com::sun::star::uno::Sequence< RowPropertyValuesSeq_t>    CellProperty
typedef std::vector<PropertyMapPtr>     PropertyMapVector1;
typedef std::vector<PropertyMapVector1> PropertyMapVector2;

#define DEF_BORDER_DIST 190  //0,19cm

class DomainMapper_Impl;
class TableStyleSheetEntry;
struct TableInfo;
@@ -66,7 +68,7 @@ class WRITERFILTER_DLLPRIVATE DomainMapperTableHandler : public TableDataHandler
    sal_Int32 m_nCellIndex;
    sal_Int32 m_nRowIndex;

    TableStyleSheetEntry * endTableGetTableStyle(TableInfo & rInfo);
    TableStyleSheetEntry * endTableGetTableStyle(TableInfo & rInfo, uno::Sequence<beans::PropertyValue>& rFrameProperties);
    CellPropertyValuesSeq_t endTableGetCellProperties(TableInfo & rInfo);
    RowPropertyValuesSeq_t endTableGetRowProperties();

diff --git a/writerfilter/source/dmapper/TablePositionHandler.cxx b/writerfilter/source/dmapper/TablePositionHandler.cxx
index 3e30919..6d32bba 100644
--- a/writerfilter/source/dmapper/TablePositionHandler.cxx
+++ b/writerfilter/source/dmapper/TablePositionHandler.cxx
@@ -7,6 +7,7 @@
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
#include <TablePositionHandler.hxx>
#include <DomainMapperTableHandler.hxx>
#include <PropertyMap.hxx>
#include <doctok/resourceids.hxx>
#include <ConversionHelper.hxx>
@@ -28,7 +29,9 @@ TablePositionHandler::TablePositionHandler() :
    m_aHorzAnchor( "text" ),
    m_aXSpec( ),
    m_nY( 0 ),
    m_nX( 0 )
    m_nX( 0 ),
    m_nLeftBorderDistance(DEF_BORDER_DIST),
    m_nRightBorderDistance(DEF_BORDER_DIST)
{
}

@@ -75,7 +78,7 @@ void TablePositionHandler::lcl_sprm(Sprm& /*rSprm*/)

uno::Sequence<beans::PropertyValue> TablePositionHandler::getTablePosition() const
{
    uno::Sequence< beans::PropertyValue > aFrameProperties(18);
    uno::Sequence< beans::PropertyValue > aFrameProperties(19);
    beans::PropertyValue* pFrameProperties = aFrameProperties.getArray();

    pFrameProperties[0].Name = "LeftBorderDistance";
@@ -132,7 +135,7 @@ uno::Sequence<beans::PropertyValue> TablePositionHandler::getTablePosition() con
    pFrameProperties[13].Name = "HoriOrientRelation";
    pFrameProperties[13].Value <<= nHoriOrientRelation;
    pFrameProperties[14].Name = "HoriOrientPosition";
    pFrameProperties[14].Value <<= m_nX;
    pFrameProperties[14].Value <<= m_nX - m_nLeftBorderDistance;


    // Vertical positioning
@@ -161,6 +164,9 @@ uno::Sequence<beans::PropertyValue> TablePositionHandler::getTablePosition() con
    pFrameProperties[17].Name = "VertOrientPosition";
    pFrameProperties[17].Value <<= m_nY;

    pFrameProperties[18].Name = "RightMargin";
    pFrameProperties[18].Value <<= m_nRightBorderDistance;

    return aFrameProperties;
}

diff --git a/writerfilter/source/dmapper/TablePositionHandler.hxx b/writerfilter/source/dmapper/TablePositionHandler.hxx
index b6ddd50..43eabbc 100644
--- a/writerfilter/source/dmapper/TablePositionHandler.hxx
+++ b/writerfilter/source/dmapper/TablePositionHandler.hxx
@@ -27,6 +27,8 @@ namespace writerfilter {
            OUString m_aXSpec;
            sal_Int32 m_nY;
            sal_Int32 m_nX;
            sal_Int32 m_nLeftBorderDistance;
            sal_Int32 m_nRightBorderDistance;

            // Properties
            virtual void lcl_attribute(Id Name, Value & val);