n#779627: VML: import mso-position-vertical:center and friends

This allows to properly position objects that are vertically and/or
horizontally centered relatively to the page.

Change-Id: I1f7e78c5b828679817cdfc72e4d90a0850b242fa
diff --git a/oox/inc/oox/vml/vmlshape.hxx b/oox/inc/oox/vml/vmlshape.hxx
index a09192a..385f9ea 100644
--- a/oox/inc/oox/vml/vmlshape.hxx
+++ b/oox/inc/oox/vml/vmlshape.hxx
@@ -70,8 +70,10 @@ struct ShapeTypeModel
    ::rtl::OUString     maHeight;               ///< Height of the shape bounding box (number with unit).
    ::rtl::OUString     maMarginLeft;           ///< X position of the shape bounding box to shape anchor (number with unit).
    ::rtl::OUString     maMarginTop;            ///< Y position of the shape bounding box to shape anchor (number with unit).
    ::rtl::OUString     maPositionHorizontalRelative; ///< The X position is relative to this.
    ::rtl::OUString     maPositionVerticalRelative; ///< The Y position is relative to this.
    ::rtl::OUString     maPositionHorizontal;   ///< The X position orientation (default: absolute).
    ::rtl::OUString     maPositionVertical;     ///< The Y position orientation.
    ::rtl::OUString     maRotation;             ///< Rotation of the shape, in degrees.
    ::rtl::OUString     maFlip;                 ///< Flip type of the shape (can be "x" or "y").
    sal_Bool            mbAutoHeight;           ///< If true, the height value is a minimum value (mostly used for textboxes)
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index 3fed530..ff4e47b 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -223,6 +223,7 @@ HoriJustify
HoriJustifyMethod
HoriOrient
HoriOrientPosition
HoriOrientRelation
HorizontalSplitMode
HorizontalSplitPositionTwips
IgnoreBlankCells
@@ -517,6 +518,7 @@ VertJustifyMethod
VerticalAlign
VerticalSplitMode
VerticalSplitPositionTwips
VertOrient
VertOrientPosition
VertOrientRelation
ViewBox
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index c9096eb3..7d8d166 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -381,6 +381,15 @@ SimpleShape::SimpleShape( Drawing& rDrawing, const OUString& rService ) :

void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel)
{
    if ( rTypeModel.maPositionHorizontal == "center" )
        rPropSet.setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::CENTER));

    if ( rTypeModel.maPositionHorizontalRelative == "page" )
        rPropSet.setAnyProperty(PROP_HoriOrientRelation, makeAny(text::RelOrientation::PAGE_FRAME));

    if ( rTypeModel.maPositionVertical == "center" )
        rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::CENTER));

    if ( rTypeModel.maPosition == "absolute" )
    {
        if (rTypeModel.moWrapAnchorX.get() == "page" && rTypeModel.moWrapAnchorY.get() == "page")
@@ -395,8 +404,16 @@ void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel)
            // Map to as-character by default, that fixes vertical position of some textframes.
            rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_CHARACTER);
        }
        // Vertical placement relative to margin, because parent style must not modify vertical position
        rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::FRAME);

        if ( rTypeModel.maPositionVerticalRelative == "page" )
        {
            rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_FRAME);
        }
        else
        {
            // Vertical placement relative to margin, because parent style must not modify vertical position
            rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::FRAME);
        }
    }
    else if( rTypeModel.maPosition == "relative" )
    {   // I'm not very sure this is correct either.
@@ -432,8 +449,6 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes 
    {
        PropertySet( xShape ).setAnyProperty( PROP_FrameIsAutomaticHeight, makeAny( maTypeModel.mbAutoHeight ) );
        PropertySet( xShape ).setAnyProperty( PROP_SizeType, makeAny( maTypeModel.mbAutoHeight ? SizeType::MIN : SizeType::FIX ) );
        if (maTypeModel.maPositionHorizontal == "center")
            PropertySet(xShape).setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::CENTER));
    }

    // Import Legacy Fragments (if any)
@@ -479,11 +494,6 @@ Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >
        }

        lcl_SetAnchorType(aPropSet, maTypeModel);

        if ( maTypeModel.maPositionVerticalRelative == "page" )
        {
            aPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_FRAME);
        }
    }
    return xShape;
}
diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx
index 165aee5..01543c3 100644
--- a/oox/source/vml/vmlshapecontext.cxx
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -361,7 +361,9 @@ void ShapeTypeContext::setStyle( const OUString& rStyle )
            else if( aName == "margin-left" )    mrTypeModel.maMarginLeft = aValue;
            else if( aName == "margin-top" )     mrTypeModel.maMarginTop = aValue;
            else if( aName == "mso-position-vertical-relative" )  mrTypeModel.maPositionVerticalRelative = aValue;
            else if( aName == "mso-position-horizontal-relative" )  mrTypeModel.maPositionHorizontalRelative = aValue;
            else if( aName == "mso-position-horizontal" ) mrTypeModel.maPositionHorizontal = aValue;
            else if( aName == "mso-position-vertical" ) mrTypeModel.maPositionVertical = aValue;
            else if( aName == "mso-fit-shape-to-text" )           mrTypeModel.mbAutoHeight = sal_True;
            else if( aName == "rotation" )       mrTypeModel.maRotation = aValue;
            else if( aName == "flip" )       mrTypeModel.maFlip = aValue;
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 92452dd..5214b49 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -35,8 +35,10 @@
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/RelOrientation.hpp>
#include <com/sun/star/text/SetVariableType.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
#include <com/sun/star/text/WrapTextMode.hpp>
#include <com/sun/star/text/XDependentTextField.hpp>
#include <com/sun/star/text/XFormField.hpp>
@@ -890,7 +892,25 @@ void Test::testN779627()
    uno::Any aValue = xTableProperties->getPropertyValue("LeftMargin");
    sal_Int32 nLeftMargin;
    aValue >>= nLeftMargin;
    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nLeftMargin);
    CPPUNIT_ASSERT_EQUAL_MESSAGE( "Left margin shouldn't take tableCellMar into account in nested tables",
            sal_Int32(0), nLeftMargin);

    /*
     * Another problem tested with this document is that the roundrect is
     * centered vertically and horizontally.
     */
    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
    uno::Reference<beans::XPropertySet> xShapeProperties( xDraws->getByIndex(2), uno::UNO_QUERY );
    sal_Int16 nValue;
    xShapeProperties->getPropertyValue("HoriOrient") >>= nValue;
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered horizontally", text::HoriOrientation::CENTER, nValue);
    xShapeProperties->getPropertyValue("HoriOrientRelation") >>= nValue;
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered horizontally relatively to page", text::RelOrientation::PAGE_FRAME, nValue);
    xShapeProperties->getPropertyValue("VertOrient") >>= nValue;
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered vertically", text::VertOrientation::CENTER, nValue);
    xShapeProperties->getPropertyValue("VertOrientRelation") >>= nValue;
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered vertically relatively to page", text::RelOrientation::PAGE_FRAME, nValue);
}

void Test::testFdo55187()