[Libreoffice-commits] core.git: Branch 'libreoffice-5-0' - 3 commits - include/oox oox/source sc/qa sc/source sd/qa svx/source

Andras Timar andras.timar at collabora.com
Thu May 28 00:08:47 PDT 2015


 include/oox/export/drawingml.hxx                  |    1 
 oox/source/export/drawingml.cxx                   |  206 ++++++++
 oox/source/export/shapes.cxx                      |   25 
 sc/qa/unit/data/ods/move-cell-anchored-shapes.ods |binary
 sc/qa/unit/subsequent_export-test.cxx             |  166 ++++++
 sc/qa/unit/ucalc.cxx                              |  100 +++
 sc/qa/unit/ucalc.hxx                              |    2 
 sc/source/core/data/drwlayer.cxx                  |   59 ++
 sd/qa/unit/data/tdf90338.odp                      |binary
 sd/qa/unit/data/xml/tdf90338_0.xml                |  561 ++++++++++++++++++++++
 sd/qa/unit/import-tests.cxx                       |    1 
 svx/source/svdraw/svdoashp.cxx                    |    1 
 12 files changed, 1110 insertions(+), 12 deletions(-)

New commits:
commit 9ad8490e1154d5667249d56a63c9c00111cafa4d
Author: Andras Timar <andras.timar at collabora.com>
Date:   Wed May 27 12:47:29 2015 +0200

    tdf#90338 related: ignore empty shape handles struct
    
    Change-Id: I486564a124cfb0d13a8b20e89cf13e752ccb7237
    Reviewed-on: https://gerrit.libreoffice.org/15923
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    (cherry picked from commit 1a4eeac14b618714bb8be9755f508ee63ac4a422)

diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index e2a5e75..735c569 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -400,8 +400,12 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
                     rProp.Value >>= bFlipV;
                 if ( rProp.Name == "AdjustmentValues" )
                     nAdjustmentValuesIndex = i;
-                else if ( rProp.Name == "Handles" ) {
-                    bHasHandles = true;
+                else if ( rProp.Name == "Handles" )
+                {
+                    uno::Sequence<beans::PropertyValue> aHandles;
+                    rProp.Value >>= aHandles;
+                    if ( aHandles.getLength() )
+                        bHasHandles = true;
                     if( !bIsDefaultObject )
                         bPredefinedHandlesUsed = false;
                     // TODO: update nAdjustmentsWhichNeedsToBeConverted here
commit 0fa10fa7ea7026de7d998776201747afda0ca6b2
Author: Andras Timar <andras.timar at collabora.com>
Date:   Tue May 26 19:35:08 2015 +0200

    tdf#90338 tdf#84254 DrawingML export fix
    
    Change-Id: I610d8099f057a2a34a1f9573d8ac16b5b8da9fc7
    Reviewed-on: https://gerrit.libreoffice.org/15918
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    (cherry picked from commit 481c185e327cb83ffcb29657d5a354eae2c4a5f3)

diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index 2707852..3b9d847 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -177,6 +177,7 @@ public:
 
     void WritePresetShape( const char* pShape );
     void WritePresetShape( const char* pShape, MSO_SPT eShapeType, bool bPredefinedHandlesUsed, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, const ::com::sun::star::beans::PropertyValue& rProp );
+    void WriteCustomGeometry( css::uno::Reference<css::drawing::XShape> rXShape );
     void WritePolyPolygon( const tools::PolyPolygon& rPolyPolygon );
     void WriteFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropSet );
     void WriteShapeStyle( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet );
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 832914f..0600f60 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -43,6 +43,10 @@
 #include <com/sun/star/container/XIndexAccess.hpp>
 #include <com/sun/star/drawing/BitmapMode.hpp>
 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
 #include <com/sun/star/drawing/LineDash.hpp>
 #include <com/sun/star/drawing/LineJoint.hpp>
 #include <com/sun/star/drawing/LineStyle.hpp>
@@ -2198,6 +2202,208 @@ void DrawingML::WritePresetShape( const char* pShape, MSO_SPT eShapeType, bool b
     mpFS->endElementNS(  XML_a, XML_prstGeom );
 }
 
+void DrawingML::WriteCustomGeometry( Reference< XShape > rXShape )
+{
+    uno::Reference< beans::XPropertySet > aXPropSet;
+    uno::Any aAny( rXShape->queryInterface(cppu::UnoType<beans::XPropertySet>::get()));
+
+    if ( ! (aAny >>= aXPropSet) )
+        return;
+
+    try
+    {
+        aAny = aXPropSet->getPropertyValue( "CustomShapeGeometry" );
+        if ( !aAny.hasValue() )
+            return;
+    }
+    catch( const ::uno::Exception& )
+    {
+        return;
+    }
+
+
+    mpFS->startElementNS( XML_a, XML_custGeom, FSEND );
+    mpFS->singleElementNS( XML_a, XML_avLst, FSEND );
+    mpFS->singleElementNS( XML_a, XML_gdLst, FSEND );
+    mpFS->singleElementNS( XML_a, XML_ahLst, FSEND );
+    mpFS->singleElementNS( XML_a, XML_rect,
+                           XML_l, "l",
+                           XML_t, "t",
+                           XML_r, "r",
+                           XML_b, "b",
+                           FSEND );
+
+    mpFS->startElementNS( XML_a, XML_pathLst, FSEND );
+
+    uno::Sequence< beans::PropertyValue > const * pGeometrySeq =
+        static_cast<uno::Sequence< beans::PropertyValue > const *>(aAny.getValue());
+
+    if ( pGeometrySeq )
+    {
+        for( int i = 0; i < pGeometrySeq->getLength(); ++i )
+        {
+            const beans::PropertyValue& rProp = (*pGeometrySeq)[ i ];
+            if ( rProp.Name == "Path" )
+            {
+                uno::Sequence<beans::PropertyValue> aPathProp;
+                rProp.Value >>= aPathProp;
+
+                uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aPairs;
+                uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments;
+                uno::Sequence<awt::Size> aPathSize;
+                bool bHasSubViewSize = false;
+                for (int j = 0; j < aPathProp.getLength(); ++j )
+                {
+                    const beans::PropertyValue& rPathProp = aPathProp[j];
+                    if (rPathProp.Name == "Coordinates")
+                        rPathProp.Value >>= aPairs;
+                    else if (rPathProp.Name == "Segments")
+                        rPathProp.Value >>= aSegments;
+                    else if (rPathProp.Name == "SubViewSize")
+                    {
+                        rPathProp.Value >>= aPathSize;
+                        bHasSubViewSize = true;
+                    }
+                }
+
+                if ( bHasSubViewSize )
+                {
+                    mpFS->startElementNS( XML_a, XML_path,
+                          XML_w, I64S( aPathSize[0].Width ),
+                          XML_h, I64S( aPathSize[0].Height ),
+                          FSEND );
+                }
+                else
+                {
+                    sal_Int32 nXMin = aPairs[0].First.Value.get<sal_Int32>();
+                    sal_Int32 nXMax = nXMin;
+                    sal_Int32 nYMin = aPairs[0].Second.Value.get<sal_Int32>();
+                    sal_Int32 nYMax = nYMin;
+
+                    for ( int j = 0; j < aPairs.getLength(); ++j )
+                    {
+                        if ( aPairs[j].First.Value.get<sal_Int32>() < nXMin )
+                            nXMin = aPairs[j].First.Value.get<sal_Int32>();
+                        if ( aPairs[j].Second.Value.get<sal_Int32>() < nYMin )
+                            nYMin = aPairs[j].Second.Value.get<sal_Int32>();
+                        if ( aPairs[j].First.Value.get<sal_Int32>() > nXMax )
+                            nXMax = aPairs[j].First.Value.get<sal_Int32>();
+                        if ( aPairs[j].Second.Value.get<sal_Int32>() > nYMax )
+                            nYMax = aPairs[j].Second.Value.get<sal_Int32>();
+                    }
+                    mpFS->startElementNS( XML_a, XML_path,
+                          XML_w, I64S( nXMax - nXMin ),
+                          XML_h, I64S( nYMax - nYMin ),
+                          FSEND );
+                }
+
+
+                int nPairIndex = 0;
+                for( int j = 0; j < aSegments.getLength(); ++j )
+                {
+                    if ( aSegments[ j ].Command == drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH )
+                    {
+                        mpFS->singleElementNS( XML_a, XML_close, FSEND );
+                    }
+                    for ( int k = 0; k < aSegments[j].Count; ++k )
+                    {
+                        switch( aSegments[ j ].Command )
+                        {
+                            case drawing::EnhancedCustomShapeSegmentCommand::MOVETO :
+                            {
+                                mpFS->startElementNS( XML_a, XML_moveTo, FSEND );
+
+                                mpFS->singleElementNS( XML_a, XML_pt,
+                                   XML_x, I64S( aPairs[nPairIndex].First.Value.get<sal_Int32>() ),
+                                   XML_y, I64S( aPairs[nPairIndex].Second.Value.get<sal_Int32>() ),
+                                   FSEND );
+
+                                mpFS->endElementNS( XML_a, XML_moveTo );
+                                nPairIndex++;
+                                break;
+                            }
+                            case drawing::EnhancedCustomShapeSegmentCommand::LINETO :
+                            {
+                                mpFS->startElementNS( XML_a, XML_lnTo, FSEND );
+                                mpFS->singleElementNS( XML_a, XML_pt,
+                                   XML_x, I64S( aPairs[nPairIndex].First.Value.get<sal_Int32>() ),
+                                   XML_y, I64S( aPairs[nPairIndex].Second.Value.get<sal_Int32>() ),
+                                   FSEND );
+                                mpFS->endElementNS( XML_a, XML_lnTo );
+                                nPairIndex++;
+                                break;
+                            }
+                            case drawing::EnhancedCustomShapeSegmentCommand::CURVETO :
+                            {
+                                mpFS->startElementNS( XML_a, XML_cubicBezTo, FSEND );
+                                for( sal_uInt8 l = 0; l <= 2; ++l )
+                                {
+                                    mpFS->singleElementNS( XML_a, XML_pt,
+                                    XML_x, I64S( aPairs[nPairIndex+l].First.Value.get<sal_Int32>() ),
+                                    XML_y, I64S( aPairs[nPairIndex+l].Second.Value.get<sal_Int32>() ),
+                                    FSEND );
+
+                                }
+                                mpFS->endElementNS( XML_a, XML_cubicBezTo );
+                                nPairIndex += 3;
+                                break;
+                            }
+                            case drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
+                            case drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
+                            {
+                                nPairIndex += 3;
+                                break;
+                            }
+                            case drawing::EnhancedCustomShapeSegmentCommand::ARCTO :
+                            case drawing::EnhancedCustomShapeSegmentCommand::ARC :
+                            case drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
+                            case drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
+                            {
+                                nPairIndex += 4;
+                                break;
+                            }
+                            case drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
+                            case drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
+                            {
+                                nPairIndex++;
+                                break;
+                            }
+                            case drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO :
+                            {
+                                mpFS->startElementNS( XML_a, XML_quadBezTo, FSEND );
+                                for( sal_uInt8 l = 0; l < 2; ++l )
+                                {
+                                    mpFS->singleElementNS( XML_a, XML_pt,
+                                    XML_x, I64S( aPairs[nPairIndex+l].First.Value.get<sal_Int32>() ),
+                                    XML_y, I64S( aPairs[nPairIndex+l].Second.Value.get<sal_Int32>() ),
+                                    FSEND );
+
+                                }
+                                mpFS->endElementNS( XML_a, XML_quadBezTo );
+                                nPairIndex += 2;
+                                break;
+                            }
+                            case drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO :
+                            {
+                                nPairIndex += 2;
+                                break;
+                            }
+                            default:
+                                // do nothing
+                                break;
+                        }
+                    }
+                }
+                mpFS->endElementNS( XML_a, XML_path );
+            }
+        }
+    }
+
+    mpFS->endElementNS( XML_a, XML_pathLst );
+
+    mpFS->endElementNS( XML_a, XML_custGeom );
+}
+
 void DrawingML::WritePolyPolygon( const tools::PolyPolygon& rPolyPolygon )
 {
     if( rPolyPolygon.Count() < 1 )
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 1dce98c..e2a5e75 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -291,6 +291,7 @@ static bool lcl_IsOnBlacklist(OUString& rShapeType)
     static
 #endif
     const std::initializer_list<OUStringLiteral> vBlacklist = {
+        OUStringLiteral("ellipse"),
         OUStringLiteral("ring"),
         OUStringLiteral("can"),
         OUStringLiteral("cube"),
@@ -478,17 +479,13 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
     else if( bHasHandles )
         bCustGeom = true;
 
-    if (bCustGeom && pShape)
+    if (bHasHandles && bCustGeom && pShape)
     {
-        basegfx::B2DPolyPolygon aB2DPolyPolygon = pShape->GetLineGeometry(true);
-        tools::PolyPolygon aPolyPolygon;
-        for( sal_uInt32 i = 0; i < aB2DPolyPolygon.count(); ++i )
-        {
-            basegfx::B2DPolygon aB2DPolygon = aB2DPolyPolygon.getB2DPolygon(i);
-            aPolyPolygon.Insert( Polygon( aB2DPolygon ), POLYPOLY_APPEND );
-        }
-
-        WritePolyPolygon( aPolyPolygon );
+        WritePolyPolygon( tools::PolyPolygon( pShape->GetLineGeometry(true) ) );
+    }
+    else if (bCustGeom && pShape)
+    {
+        WriteCustomGeometry( xShape );
     }
     else // preset geometry
     {
diff --git a/sd/qa/unit/data/tdf90338.odp b/sd/qa/unit/data/tdf90338.odp
new file mode 100644
index 0000000..55739bb
Binary files /dev/null and b/sd/qa/unit/data/tdf90338.odp differ
diff --git a/sd/qa/unit/data/xml/tdf90338_0.xml b/sd/qa/unit/data/xml/tdf90338_0.xml
new file mode 100644
index 0000000..7821ceb
--- /dev/null
+++ b/sd/qa/unit/data/xml/tdf90338_0.xml
@@ -0,0 +1,561 @@
+<?xml version="1.0"?>
+<XShapes>
+ <XShape positionX="5498" positionY="2715" sizeX="11630" sizeY="8623" type="com.sun.star.drawing.CustomShape" name="CustomShape 1" fontHeight="18.000000" fontColor="ffffffff" textAutoGrowHeight="false" textAutoGrowWidth="false" textContourFrame="false" textFitToSize="NONE" textHorizontalAdjust="BLOCK" textVerticalAdjust="TOP" textLeftDistance="250" textRightDistance="250" textUpperDistance="125" textLowerDistance="125" textMaximumFrameHeight="0" textMaximumFrameWidth="0" textMinimumFrameHeight="0" textMinimumFrameWidth="0" textAnimationAmount="0" textAnimationCount="0" textAnimationDelay="0" textAnimationDirection="LEFT" textAnimationKind="NONE" textAnimationStartInside="false" textAnimationStopInside="false" textWritingMode="LR_TB" fillStyle="SOLID" fillColor="e7e6e6" fillTransparence="0" fillTransparenceGradientName="">
+  <FillTransparenceGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
+  <FillGradient style="LINEAR" startColor="3465a4" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
+  <FillHatch style="SINGLE" color="3465a4" distance="20" angle="0"/>
+  <FillBitmap width="32" height="32"/>
+  <LineDash style="RECT" dots="1" dotLen="20" dashes="1" dashLen="20" distance="20"/>
+  <LineStart/>
+  <LineEnd/>
+  <Transformation>
+   <Line1 column1="11631.000000" column2="0.000000" column3="5498.000000"/>
+   <Line2 column1="0.000000" column2="8624.000000" column3="2715.000000"/>
+   <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
+  </Transformation>
+  <CustomShapeGeometry>
+   <PropertyValue name="AdjustmentValues">
+    <AdjustmentValues/>
+   </PropertyValue>
+   <PropertyValue name="Equations" handle="0" propertyState="DIRECT_VALUE"/>
+   <PropertyValue name="Handles">
+    <Handles/>
+   </PropertyValue>
+   <PropertyValue name="MirroredX" value="true" handle="0" propertyState="DIRECT_VALUE"/>
+   <PropertyValue name="MirroredY" value="false" handle="0" propertyState="DIRECT_VALUE"/>
+   <PropertyValue name="Path">
+    <Path>
+     <PropertyValue name="Coordinates">
+      <Coordinates>
+       <EnhancedCustomShapeParameterPair>
+        <First value="626694" type="0"/>
+        <Second value="500766" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="658274" type="0"/>
+        <Second value="500766" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="683875" type="0"/>
+        <Second value="526366" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="683875" type="0"/>
+        <Second value="557947" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="683875" type="0"/>
+        <Second value="589527" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="658274" type="0"/>
+        <Second value="615128" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="626694" type="0"/>
+        <Second value="615128" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="595113" type="0"/>
+        <Second value="615128" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="569513" type="0"/>
+        <Second value="589527" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="569513" type="0"/>
+        <Second value="557947" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="569513" type="0"/>
+        <Second value="526366" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="595113" type="0"/>
+        <Second value="500766" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="626694" type="0"/>
+        <Second value="500766" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="352919" type="0"/>
+        <Second value="500765" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="384499" type="0"/>
+        <Second value="500765" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="410100" type="0"/>
+        <Second value="526366" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="410100" type="0"/>
+        <Second value="557946" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="410100" type="0"/>
+        <Second value="589527" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="384499" type="0"/>
+        <Second value="615127" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="352919" type="0"/>
+        <Second value="615127" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="321338" type="0"/>
+        <Second value="615127" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="295737" type="0"/>
+        <Second value="589527" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="295737" type="0"/>
+        <Second value="557946" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="295737" type="0"/>
+        <Second value="526366" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="321338" type="0"/>
+        <Second value="500765" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="352919" type="0"/>
+        <Second value="500765" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="489807" type="0"/>
+        <Second value="202385" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="523492" type="0"/>
+        <Second value="202385" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="550800" type="0"/>
+        <Second value="229692" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="550800" type="0"/>
+        <Second value="263378" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="550800" type="0"/>
+        <Second value="297063" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="523492" type="0"/>
+        <Second value="324371" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="489807" type="0"/>
+        <Second value="324371" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="456122" type="0"/>
+        <Second value="324371" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="428814" type="0"/>
+        <Second value="297063" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="428814" type="0"/>
+        <Second value="263378" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="428814" type="0"/>
+        <Second value="229692" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="456122" type="0"/>
+        <Second value="202385" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="489807" type="0"/>
+        <Second value="202385" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="175791" type="0"/>
+        <Second value="200142" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="137652" type="0"/>
+        <Second value="200142" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="106735" type="0"/>
+        <Second value="246628" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="106735" type="0"/>
+        <Second value="303972" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="106735" type="0"/>
+        <Second value="361316" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="137652" type="0"/>
+        <Second value="407802" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="175791" type="0"/>
+        <Second value="407802" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="154055" type="0"/>
+        <Second value="383291" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="141263" type="0"/>
+        <Second value="344823" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="141263" type="0"/>
+        <Second value="303972" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="141263" type="0"/>
+        <Second value="263120" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="154055" type="0"/>
+        <Second value="224653" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="175791" type="0"/>
+        <Second value="200142" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="803821" type="0"/>
+        <Second value="200142" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="825557" type="0"/>
+        <Second value="224653" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="838349" type="0"/>
+        <Second value="263120" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="838349" type="0"/>
+        <Second value="303972" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="838349" type="0"/>
+        <Second value="344823" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="825557" type="0"/>
+        <Second value="383291" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="803821" type="0"/>
+        <Second value="407802" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="841960" type="0"/>
+        <Second value="407802" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="872877" type="0"/>
+        <Second value="361316" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="872877" type="0"/>
+        <Second value="303972" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="872877" type="0"/>
+        <Second value="246628" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="841960" type="0"/>
+        <Second value="200142" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="803821" type="0"/>
+        <Second value="200142" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="489807" type="0"/>
+        <Second value="97034" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="397937" type="0"/>
+        <Second value="97034" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="323463" type="0"/>
+        <Second value="171509" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="323463" type="0"/>
+        <Second value="263378" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="323463" type="0"/>
+        <Second value="355247" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="397937" type="0"/>
+        <Second value="429722" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="489807" type="0"/>
+        <Second value="429722" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="581676" type="0"/>
+        <Second value="429722" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="656151" type="0"/>
+        <Second value="355247" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="656151" type="0"/>
+        <Second value="263378" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="656151" type="0"/>
+        <Second value="171509" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="581676" type="0"/>
+        <Second value="97034" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="489807" type="0"/>
+        <Second value="97034" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="139849" type="0"/>
+        <Second value="93700" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="62613" type="0"/>
+        <Second value="93700" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="0" type="0"/>
+        <Second value="187842" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="0" type="0"/>
+        <Second value="303971" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="0" type="0"/>
+        <Second value="420100" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="62613" type="0"/>
+        <Second value="514242" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="139849" type="0"/>
+        <Second value="514242" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="80774" type="0"/>
+        <Second value="482466" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="41350" type="0"/>
+        <Second value="398306" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="41350" type="0"/>
+        <Second value="303971" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="41350" type="0"/>
+        <Second value="209636" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="80774" type="0"/>
+        <Second value="125476" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="139849" type="0"/>
+        <Second value="93700" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="839763" type="0"/>
+        <Second value="93700" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="898838" type="0"/>
+        <Second value="125476" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="938262" type="0"/>
+        <Second value="209636" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="938262" type="0"/>
+        <Second value="303971" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="938262" type="0"/>
+        <Second value="398306" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="898838" type="0"/>
+        <Second value="482466" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="839763" type="0"/>
+        <Second value="514242" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="916999" type="0"/>
+        <Second value="514242" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="979612" type="0"/>
+        <Second value="420100" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="979612" type="0"/>
+        <Second value="303971" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="979612" type="0"/>
+        <Second value="187842" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="916999" type="0"/>
+        <Second value="93700" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="839763" type="0"/>
+        <Second value="93700" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="489806" type="0"/>
+        <Second value="69310" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="596987" type="0"/>
+        <Second value="69310" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="683875" type="0"/>
+        <Second value="156198" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="683875" type="0"/>
+        <Second value="263379" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="683875" type="0"/>
+        <Second value="370560" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="596987" type="0"/>
+        <Second value="457447" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="489806" type="0"/>
+        <Second value="457447" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="382625" type="0"/>
+        <Second value="457447" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="295738" type="0"/>
+        <Second value="370560" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="295738" type="0"/>
+        <Second value="263379" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="295738" type="0"/>
+        <Second value="156198" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="382625" type="0"/>
+        <Second value="69310" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="489806" type="0"/>
+        <Second value="69310" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="735857" type="0"/>
+        <Second value="0" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="243755" type="0"/>
+        <Second value="0" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="243755" type="0"/>
+        <Second value="658446" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+       <EnhancedCustomShapeParameterPair>
+        <First value="735857" type="0"/>
+        <Second value="658446" type="0"/>
+       </EnhancedCustomShapeParameterPair>
+      </Coordinates>
+     </PropertyValue>
+     <PropertyValue name="Segments">
+      <Segments>
+       <EnhancedCustomShapeSegment command="1" count="1"/>
+       <EnhancedCustomShapeSegment command="3" count="4"/>
+       <EnhancedCustomShapeSegment command="4" count="0"/>
+       <EnhancedCustomShapeSegment command="1" count="1"/>
+       <EnhancedCustomShapeSegment command="3" count="4"/>
+       <EnhancedCustomShapeSegment command="4" count="0"/>
+       <EnhancedCustomShapeSegment command="1" count="1"/>
+       <EnhancedCustomShapeSegment command="3" count="4"/>
+       <EnhancedCustomShapeSegment command="4" count="0"/>
+       <EnhancedCustomShapeSegment command="1" count="1"/>
+       <EnhancedCustomShapeSegment command="3" count="4"/>
+       <EnhancedCustomShapeSegment command="4" count="0"/>
+       <EnhancedCustomShapeSegment command="1" count="1"/>
+       <EnhancedCustomShapeSegment command="3" count="4"/>
+       <EnhancedCustomShapeSegment command="4" count="0"/>
+       <EnhancedCustomShapeSegment command="1" count="1"/>
+       <EnhancedCustomShapeSegment command="3" count="4"/>
+       <EnhancedCustomShapeSegment command="4" count="0"/>
+       <EnhancedCustomShapeSegment command="1" count="1"/>
+       <EnhancedCustomShapeSegment command="3" count="4"/>
+       <EnhancedCustomShapeSegment command="4" count="0"/>
+       <EnhancedCustomShapeSegment command="1" count="1"/>
+       <EnhancedCustomShapeSegment command="3" count="4"/>
+       <EnhancedCustomShapeSegment command="4" count="0"/>
+       <EnhancedCustomShapeSegment command="1" count="1"/>
+       <EnhancedCustomShapeSegment command="3" count="4"/>
+       <EnhancedCustomShapeSegment command="4" count="0"/>
+       <EnhancedCustomShapeSegment command="1" count="1"/>
+       <EnhancedCustomShapeSegment command="2" count="3"/>
+       <EnhancedCustomShapeSegment command="4" count="0"/>
+       <EnhancedCustomShapeSegment command="5" count="0"/>
+      </Segments>
+     </PropertyValue>
+     <PropertyValue name="SubViewSize" handle="0" propertyState="DIRECT_VALUE"/>
+     <PropertyValue name="TextFrames" handle="0" propertyState="DIRECT_VALUE"/>
+    </Path>
+   </PropertyValue>
+   <PropertyValue name="Type" value="ooxml-non-primitive" handle="0" propertyState="DIRECT_VALUE"/>
+   <PropertyValue name="ViewBox">
+    <ViewBox x="0" y="0" width="0" height="0"/>
+   </PropertyValue>
+  </CustomShapeGeometry>
+ </XShape>
+</XShapes>
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 6b7f993..440271e 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -192,6 +192,7 @@ void SdImportTest::testDocumentLayout()
         { "fdo71434.pptx", "xml/fdo71434_", PPTX, -1 },
         { "n902652.pptx", "xml/n902652_", PPTX, -1 },
         { "tdf90403.pptx", "xml/tdf90403_", PPTX, -1 },
+        { "tdf90338.odp", "xml/tdf90338_", ODP, PPTX },
         // { "pptx/n828390.pptx", "pptx/xml/n828390_", PPTX, PPTX }, // Example
     };
 
commit dabe4ad3bf21b6b6c9eadbd7e78262a1f59af771
Author: Henry Castro <hcastro at collabora.com>
Date:   Fri Apr 24 16:55:01 2015 -0400

    Resolves tdf#67712 form controls and draw objects
    
    anchored to cell but changes position after reopening
    
    Also included tdf#68797 "FILEOPEN lost position of lines
    anchored to cell". It was marked as duplicate but the
    step to reproduce are different.
    
    Conflicts:
    	sc/qa/unit/subsequent_filters-test.cxx
    
    Conflicts:
    	sc/qa/unit/subsequent_export-test.cxx
    
    Reviewed-on: https://gerrit.libreoffice.org/15523
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    (cherry picked from commit 487880b6882ec01c1b4679eae60bec484272a86b)
    
    Conflicts:
    	sc/qa/unit/subsequent_export-test.cxx
    
    Change-Id: Ia1c4010f118749256077a0ecad6ca16b867d22f7

diff --git a/sc/qa/unit/data/ods/move-cell-anchored-shapes.ods b/sc/qa/unit/data/ods/move-cell-anchored-shapes.ods
new file mode 100644
index 0000000..9ad1568
Binary files /dev/null and b/sc/qa/unit/data/ods/move-cell-anchored-shapes.ods differ
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index 60b4b5c..bccb0cd 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -22,6 +22,7 @@
 #include "helper/xpath.hxx"
 #include "helper/shared_test_impl.hxx"
 
+#include "userdat.hxx"
 #include "docsh.hxx"
 #include "patattr.hxx"
 #include "scitems.hxx"
@@ -144,6 +145,7 @@ public:
     void testTextUnderlineColor();
     void testSheetRunParagraphProperty();
     void testHiddenShape();
+    void testMoveCellAnchoredShapes();
 
     CPPUNIT_TEST_SUITE(ScExportTest);
     CPPUNIT_TEST(test);
@@ -198,6 +200,7 @@ public:
     CPPUNIT_TEST(testTextUnderlineColor);
     CPPUNIT_TEST(testSheetRunParagraphProperty);
     CPPUNIT_TEST(testHiddenShape);
+    CPPUNIT_TEST(testMoveCellAnchoredShapes);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -2642,6 +2645,169 @@ void ScExportTest::testHiddenShape()
     assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:nvSpPr/xdr:cNvPr", "hidden", "1");
 }
 
+void ScExportTest::testMoveCellAnchoredShapes()
+{
+    ScDocShellRef xDocSh = loadDoc("move-cell-anchored-shapes.", ODS);
+    CPPUNIT_ASSERT_MESSAGE("Failed to load move-cell-anchored-shapes.ods", xDocSh.Is());
+
+    // There are two cell-anchored objects on the first sheet.
+    ScDocument& rDoc = xDocSh->GetDocument();
+
+    CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc.GetTableCount() > 0);
+
+    ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
+    SdrPage* pPage = pDrawLayer->GetPage(0);
+    CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
+    SdrObject* pObj = pPage->GetObj(0);
+    CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
+
+    // Check cell anchor state
+    ScAnchorType oldType = ScDrawLayer::GetAnchorType(*pObj);
+    CPPUNIT_ASSERT_MESSAGE( "Failed to get anchor type", oldType == SCA_CELL );
+
+    // Get anchor data
+    ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj, false);
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
+    CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
+
+    ScAddress aDataStart = pData->maStart;
+    ScAddress aDataEnd   = pData->maEnd;
+
+    // Get non rotated anchor data
+    ScDrawObjData* pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
+    CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty());
+
+    ScAddress aNDataStart = pNData->maStart;
+    ScAddress aNDataEnd   = pNData->maEnd;
+    CPPUNIT_ASSERT_EQUAL(aDataStart, aNDataStart);
+    CPPUNIT_ASSERT_EQUAL(aDataEnd , aNDataEnd);
+
+    // Insert 2 rows.
+    rDoc.InsertRow(ScRange( 0, aDataStart.Row() - 1, 0, MAXCOL, aDataStart.Row(), 0));
+
+    // Get anchor data
+    pData = ScDrawLayer::GetObjData(pObj, false);
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
+    CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
+
+    // Get non rotated anchor data
+    pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
+    CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty());
+
+    // Check if data has moved to new rows
+    CPPUNIT_ASSERT_EQUAL( pData->maStart.Row(), aDataStart.Row() + 2 );
+    CPPUNIT_ASSERT_EQUAL( pData->maEnd.Row(), aDataEnd.Row() + 2 );
+
+    CPPUNIT_ASSERT_EQUAL( pNData->maStart.Row(), aNDataStart.Row() + 2 );
+    CPPUNIT_ASSERT_EQUAL( pNData->maEnd.Row(), aNDataEnd.Row() + 2 );
+
+    // Save the anchor data
+    aDataStart = pData->maStart;
+    aDataEnd   = pData->maEnd;
+    aNDataStart = pNData->maStart;
+    aNDataEnd   = pNData->maEnd;
+
+    // Save the document and load again to check anchor persist
+    ScDocShellRef xDocSh1 = saveAndReload(&(*xDocSh), ODS);
+
+    // There are two cell-anchored objects on the first sheet.
+    ScDocument& rDoc1 = xDocSh1->GetDocument();
+
+    CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc1.GetTableCount() > 0);
+
+    pDrawLayer = rDoc1.GetDrawLayer();
+    pPage = pDrawLayer->GetPage(0);
+    CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
+    pObj = pPage->GetObj(0);
+    CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
+
+    // Check cell anchor state
+    oldType = ScDrawLayer::GetAnchorType(*pObj);
+    CPPUNIT_ASSERT_MESSAGE( "Failed to get anchor type", oldType == SCA_CELL );
+
+    // Get anchor data
+    pData = ScDrawLayer::GetObjData(pObj, false);
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
+    CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
+
+    // Get non rotated anchor data
+    pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
+    CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty());
+
+    // Check if data after save it
+    CPPUNIT_ASSERT_EQUAL(pData->maStart, aDataStart);
+    CPPUNIT_ASSERT_EQUAL(pData->maEnd , aDataEnd);
+
+    CPPUNIT_ASSERT_EQUAL(pNData->maStart, aNDataStart);
+    CPPUNIT_ASSERT_EQUAL(pNData->maEnd , aNDataEnd);
+
+    // Insert a column.
+    rDoc1.InsertCol(ScRange( aDataStart.Col(), 0 , 0 , aDataStart.Col(), MAXROW, 0 ));
+
+    // Get anchor data
+    pData = ScDrawLayer::GetObjData(pObj, false);
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
+    CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
+
+    // Get non rotated anchor data
+    pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
+    CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty());
+
+    // Check if data has moved to new rows
+    CPPUNIT_ASSERT_EQUAL(pData->maStart.Col(), SCCOL(aDataStart.Col() + 1));
+    CPPUNIT_ASSERT_EQUAL(pData->maEnd.Col() , SCCOL(aDataEnd.Col() + 1));
+
+    CPPUNIT_ASSERT_EQUAL(pNData->maStart.Col(), SCCOL(aNDataStart.Col() + 1));
+    CPPUNIT_ASSERT_EQUAL(pNData->maEnd.Col() , SCCOL(aNDataEnd.Col() + 1));
+
+    // Save the anchor data
+    aDataStart = pData->maStart;
+    aDataEnd   = pData->maEnd;
+    aNDataStart = pNData->maStart;
+    aNDataEnd   = pNData->maEnd;
+
+    // Save the document and load again to check anchor persist
+    ScDocShellRef xDocSh2 = saveAndReload(&(*xDocSh1), ODS);
+
+    // There are two cell-anchored objects on the first sheet.
+    ScDocument& rDoc2 = xDocSh2->GetDocument();
+
+    CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc2.GetTableCount() > 0);
+
+    pDrawLayer = rDoc2.GetDrawLayer();
+    pPage = pDrawLayer->GetPage(0);
+    CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
+    pObj = pPage->GetObj(0);
+    CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
+
+    // Check cell anchor state
+    oldType = ScDrawLayer::GetAnchorType(*pObj);
+    CPPUNIT_ASSERT_MESSAGE( "Failed to get anchor type", oldType == SCA_CELL );
+
+    // Get anchor data
+    pData = ScDrawLayer::GetObjData(pObj, false);
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
+    CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
+
+    // Get non rotated anchor data
+    pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
+    CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty());
+
+    // Check if data after save it
+    CPPUNIT_ASSERT_EQUAL(pData->maStart, aDataStart);
+    CPPUNIT_ASSERT_EQUAL(pData->maEnd , aDataEnd);
+
+    CPPUNIT_ASSERT_EQUAL(pNData->maStart, aNDataStart);
+    CPPUNIT_ASSERT_EQUAL(pNData->maEnd , aNDataEnd);
+
+    xDocSh2->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index ad0ae3d..494b535 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -6540,6 +6540,106 @@ void Test::testCopyPasteMatrixFormula()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testUndoDataAnchor()
+{
+    m_pDoc->InsertTab(0, "Tab1");
+    CPPUNIT_ASSERT_MESSAGE("There should be only 1 sheets to begin with", m_pDoc->GetTableCount() == 1);
+
+    m_pDoc->InitDrawLayer();
+    ScDrawLayer* pDrawLayer = m_pDoc->GetDrawLayer();
+    CPPUNIT_ASSERT_MESSAGE("No drawing layer.", pDrawLayer);
+    SdrPage* pPage = pDrawLayer->GetPage(0);
+    CPPUNIT_ASSERT_MESSAGE("No page instance for the 1st sheet.", pPage);
+
+    // Insert an object.
+    Rectangle aObjRect(2,1000,100,1100);
+    SdrObject* pObj = new SdrRectObj(aObjRect);
+    pPage->InsertObject(pObj);
+    ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0);
+
+    // Get anchor data
+    ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj, false);
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
+
+    ScAddress aOldStart = pData->maStart;
+    ScAddress aOldEnd   = pData->maEnd;
+
+    // Get non rotated anchor data
+    ScDrawObjData* pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
+
+    ScAddress aNOldStart = pNData->maStart;
+    ScAddress aNOldEnd   = pNData->maEnd;
+    CPPUNIT_ASSERT_EQUAL(aOldStart, aNOldStart);
+    CPPUNIT_ASSERT_EQUAL(aOldEnd, aNOldEnd);
+
+    //pDrawLayer->BeginCalcUndo(false);
+    // Insert a new row at row 3.
+    ScDocFunc& rFunc = getDocShell().GetDocFunc();
+    ScMarkData aMark;
+    aMark.SelectOneTable(0);
+    rFunc.InsertCells(ScRange( 0, aOldStart.Row() - 1, 0, MAXCOL, aOldStart.Row(), 0 ), &aMark, INS_INSROWS, true, true, false);
+
+    pData = ScDrawLayer::GetObjData(pObj, false);
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
+
+    ScAddress aNewStart = pData->maStart;
+    ScAddress aNewEnd   = pData->maEnd;
+
+    // Get non rotated anchor data
+    pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
+
+    ScAddress aNNewStart = pNData->maStart;
+    ScAddress aNNewEnd   = pNData->maEnd;
+    CPPUNIT_ASSERT_EQUAL(aNewStart, aNNewStart);
+    CPPUNIT_ASSERT_EQUAL(aNewEnd, aNNewEnd);
+    CPPUNIT_ASSERT_MESSAGE("Failed to compare Address.", aNewStart  != aOldStart  && aNewEnd  != aOldEnd &&
+                                                         aNNewStart != aNOldStart && aNNewEnd != aNOldEnd );
+
+    SfxUndoManager* pUndoMgr = m_pDoc->GetUndoManager();
+    CPPUNIT_ASSERT(pUndoMgr);
+    pUndoMgr->Undo();
+
+    // Check state
+    ScAnchorType oldType = ScDrawLayer::GetAnchorType(*pObj);
+    CPPUNIT_ASSERT_MESSAGE( "Failed to check state SCA_CELL.", oldType == SCA_CELL );
+
+    // Get anchor data
+    pData = ScDrawLayer::GetObjData(pObj, false);
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
+
+    // Get non rotated anchor data
+    pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
+
+    // Check if data has moved to new rows
+    CPPUNIT_ASSERT_EQUAL(pData->maStart, aOldStart);
+    CPPUNIT_ASSERT_EQUAL(pData->maEnd, aOldEnd);
+
+    CPPUNIT_ASSERT_EQUAL(pNData->maStart, aNOldStart);
+    CPPUNIT_ASSERT_EQUAL(pNData->maEnd, aNOldEnd);
+
+    pUndoMgr->Redo();
+
+    // Get anchor data
+    pData = ScDrawLayer::GetObjData(pObj, false);
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
+
+    // Get non rotated anchor data
+    pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
+    CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
+
+    // Check if data has moved to new rows
+    CPPUNIT_ASSERT_EQUAL(pData->maStart, aNewStart);
+    CPPUNIT_ASSERT_EQUAL(pData->maEnd, aNewEnd);
+
+    CPPUNIT_ASSERT_EQUAL(pNData->maStart, aNNewStart);
+    CPPUNIT_ASSERT_EQUAL(pNData->maEnd, aNNewEnd);
+
+    m_pDoc->DeleteTab(0);
+}
+
 ScDocShell* Test::findLoadedDocShellByName(const OUString& rName)
 {
     TypeId aType(TYPE(ScDocShell));
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index a2bd053..afc4d0a 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -434,6 +434,7 @@ public:
 
     // tdf#80137
     void testCopyPasteMatrixFormula();
+    void testUndoDataAnchor();
 
     CPPUNIT_TEST_SUITE(Test);
 #if CALC_TEST_PERF
@@ -643,6 +644,7 @@ public:
     CPPUNIT_TEST(testColumnFindEditCells);
     CPPUNIT_TEST(testSetStringAndNote);
     CPPUNIT_TEST(testCopyPasteMatrixFormula);
+    CPPUNIT_TEST(testUndoDataAnchor);
     CPPUNIT_TEST_SUITE_END();
 
 private:
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 3b4e110..27e47c8 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -27,6 +27,7 @@
 #include <com/sun/star/embed/ElementModes.hpp>
 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
 #include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
 
 #include "scitems.hxx"
 #include <editeng/eeitem.hxx>
@@ -116,6 +117,14 @@ void ScUndoObjData::Undo()
         pData->maStart = aOldStt;
         pData->maEnd = aOldEnd;
     }
+
+    // Undo also an untransformed anchor
+    pData = ScDrawLayer::GetNonRotatedObjData( pObj );
+    if (pData)
+    {
+        pData->maStart = aOldStt;
+        pData->maEnd = aOldEnd;
+    }
 }
 
 void ScUndoObjData::Redo()
@@ -127,6 +136,14 @@ void ScUndoObjData::Redo()
         pData->maStart = aNewStt;
         pData->maEnd = aNewEnd;
     }
+
+    // Redo also an untransformed anchor
+    pData = ScDrawLayer::GetNonRotatedObjData( pObj );
+    if (pData)
+    {
+        pData->maStart = aNewStt;
+        pData->maEnd = aNewEnd;
+    }
 }
 
 ScUndoAnchorData::ScUndoAnchorData( SdrObject* pObjP, ScDocument* pDoc, SCTAB nTab ) :
@@ -537,6 +554,15 @@ void ScDrawLayer::MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SC
             {
                 if ( pObj->ISA( SdrRectObj ) && pData->maStart.IsValid() && pData->maEnd.IsValid() )
                     pData->maStart.PutInOrder( pData->maEnd );
+
+                // Update also an untransformed anchor thats what we stored ( and still do ) to xml
+                ScDrawObjData* pNoRotatedAnchor = GetNonRotatedObjData( pObj, false );
+                if ( pNoRotatedAnchor )
+                {
+                    pNoRotatedAnchor->maStart = pData->maStart;
+                    pNoRotatedAnchor->maEnd = pData->maEnd;
+                }
+
                 AddCalcUndo( new ScUndoObjData( pObj, aOldStt, aOldEnd, pData->maStart, pData->maEnd ) );
                 RecalcPos( pObj, *pData, bNegativePage, bUpdateNoteCaptionPos );
             }
@@ -801,6 +827,39 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati
         ScDrawObjData& rNoRotatedAnchor = *GetNonRotatedObjData( pObj, true );
         if (rData.maLastRect.IsEmpty())
         {
+            // Every shape it is saved with an negative offset relative to cell
+            if (ScDrawLayer::GetAnchorType(*pObj) == SCA_CELL)
+            {
+                double fRotate(0.0);
+                double fShearX(0.0);
+
+                Point aPoint;
+                Rectangle aRect;
+
+                basegfx::B2DTuple aScale;
+                basegfx::B2DTuple aTranslate;
+                basegfx::B2DPolyPolygon aPolyPolygon;
+                basegfx::B2DHomMatrix aOriginalMatrix;
+
+                aRect = pDoc->GetMMRect(nCol1, nRow1, nCol1 , nRow1, nTab1);
+
+                if (bNegativePage)
+                    aPoint.X() = aRect.Right();
+                else
+                    aPoint.X() = aRect.Left();
+                aPoint.Y() = aRect.Top();
+
+                pObj->TRGetBaseGeometry(aOriginalMatrix, aPolyPolygon);
+                aOriginalMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+                aTranslate += ::basegfx::B2DTuple(aPoint.X(), aPoint.Y());
+                aOriginalMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
+                    aScale,
+                    fShearX,
+                    fRotate,
+                    aTranslate);
+                pObj->TRSetBaseGeometry(aOriginalMatrix, aPolyPolygon);
+            }
+
             // It's confusing ( but blame that we persist the anchor in terms of unrotated shape )
             // that the initial anchor we get here is in terms of an unrotated shape ( if the shape is rotated )
             // we need to save the old anchor ( for persisting ) and also track any resize or repositions that happen.
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx
index 4ea4c4d..00cff5f 100644
--- a/svx/source/svdraw/svdoashp.cxx
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -3003,6 +3003,7 @@ void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix,
     }
 
     // reset object shear and rotations
+    fObjectRotation = 0.0;
     aGeo.nRotationAngle = 0;
     aGeo.RecalcSinCos();
     aGeo.nShearAngle = 0;


More information about the Libreoffice-commits mailing list