include/oox/export/drawingml.hxx         |    4 +-
 oox/source/export/drawingml.cxx          |   18 +++++++---
 oox/source/export/shapes.cxx             |   55 +++++++++++++++++++++----------
 sd/qa/unit/data/pptx/tdf111884.pptx      |binary
 sd/qa/unit/export-tests-ooxml1.cxx       |   43 +++++++++++++++++++-----
 sd/source/filter/eppt/pptx-epptooxml.cxx |    9 -----
 6 files changed, 90 insertions(+), 39 deletions(-)

New commits:
commit 42c70214dc3000b609fa4ee8063b36bd9a2bdbe1
Author: Jan Holesovsky <ke...@collabora.com>
Date:   Thu Aug 31 18:32:58 2017 +0200

    tdf#111884: Implement export of group shapes in pptx.
    
    Contains also:
    
    tdf#111884: Unit test.
    related tdf#111884: GroupShapes are now handled in oox.
    
    Change-Id: If12984c0670db6396cbfd0dcb8ae1f5a9b591705
    Reviewed-on: https://gerrit.libreoffice.org/41766
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Jan Holesovsky <ke...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/42021
    Tested-by: Jan Holesovsky <ke...@collabora.com>

diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index 97d8dff58de6..d9216d2c6bf4 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -190,8 +190,8 @@ public:
 
     void WriteShapeTransformation( const css::uno::Reference< 
css::drawing::XShape >& rXShape,
                   sal_Int32 nXmlNamespace, bool bFlipH = false, bool bFlipV = 
false, bool bSuppressRotation = false );
-    void WriteTransformation( const Rectangle& rRectangle,
-                  sal_Int32 nXmlNamespace, bool bFlipH = false, bool bFlipV = 
false, sal_Int32 nRotation = 0 );
+    void WriteTransformation(const Rectangle& rRectangle,
+                  sal_Int32 nXmlNamespace, bool bFlipH = false, bool bFlipV = 
false, sal_Int32 nRotation = 0, bool bIsGroupShape = false);
 
     void WriteText( const css::uno::Reference< css::uno::XInterface >& 
rXIface, const OUString& presetWarp, bool bBodyPr = true, bool bText = true, 
sal_Int32 nXmlNamespace = 0);
     void WriteParagraph( const css::uno::Reference< css::text::XTextContent >& 
rParagraph,
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index c8d148aeb1c2..bb90a48eb96d 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1142,8 +1142,8 @@ void DrawingML::WriteStretch( const css::uno::Reference< 
css::beans::XPropertySe
     mpFS->endElementNS( XML_a, XML_stretch );
 }
 
-void DrawingML::WriteTransformation( const Rectangle& rRect,
-        sal_Int32 nXmlNamespace, bool bFlipH, bool bFlipV, sal_Int32 nRotation 
)
+void DrawingML::WriteTransformation(const Rectangle& rRect,
+        sal_Int32 nXmlNamespace, bool bFlipH, bool bFlipV, sal_Int32 
nRotation, bool bIsGroupShape)
 {
     mpFS->startElementNS( nXmlNamespace, XML_xfrm,
                           XML_flipH, bFlipH ? "1" : nullptr,
@@ -1162,6 +1162,12 @@ void DrawingML::WriteTransformation( const Rectangle& 
rRect,
     mpFS->singleElementNS( XML_a, XML_off, XML_x, IS( 
oox::drawingml::convertHmmToEmu( nLeft ) ), XML_y, IS( 
oox::drawingml::convertHmmToEmu( nTop ) ), FSEND );
     mpFS->singleElementNS( XML_a, XML_ext, XML_cx, IS( 
oox::drawingml::convertHmmToEmu( rRect.GetWidth() ) ), XML_cy, IS( 
oox::drawingml::convertHmmToEmu( rRect.GetHeight() ) ), FSEND );
 
+    if (GetDocumentType() != DOCUMENT_DOCX && bIsGroupShape)
+    {
+        mpFS->singleElementNS(XML_a, XML_chOff, XML_x, 
IS(oox::drawingml::convertHmmToEmu(nLeft)), XML_y, 
IS(oox::drawingml::convertHmmToEmu(nTop)), FSEND);
+        mpFS->singleElementNS(XML_a, XML_chExt, XML_cx, 
IS(oox::drawingml::convertHmmToEmu(rRect.GetWidth())), XML_cy, 
IS(oox::drawingml::convertHmmToEmu(rRect.GetHeight())), FSEND);
+    }
+
     mpFS->endElementNS( nXmlNamespace, XML_xfrm );
 }
 
@@ -1173,7 +1179,7 @@ void DrawingML::WriteShapeTransformation( const 
Reference< XShape >& rXShape, sa
     awt::Point aPos = rXShape->getPosition();
     awt::Size aSize = rXShape->getSize();
 
-    if (m_xParent.is())
+    if (GetDocumentType() == DOCUMENT_DOCX && m_xParent.is())
     {
         awt::Point aParentPos = m_xParent->getPosition();
         aPos.X -= aParentPos.X;
@@ -1202,7 +1208,11 @@ void DrawingML::WriteShapeTransformation( const 
Reference< XShape >& rXShape, sa
         if (xPropertySetInfo->hasPropertyByName("RotateAngle"))
             xPropertySet->getPropertyValue("RotateAngle") >>= nRotation;
     }
-    WriteTransformation( Rectangle( Point( aPos.X, aPos.Y ), Size( 
aSize.Width, aSize.Height ) ), nXmlNamespace, bFlipH, bFlipV, 
OOX_DRAWINGML_EXPORT_ROTATE_CLOCKWISIFY(nRotation) );
+
+    uno::Reference<lang::XServiceInfo> xServiceInfo(rXShape, 
uno::UNO_QUERY_THROW);
+    bool bIsGroupShape = (xServiceInfo.is() && 
xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"));
+
+    WriteTransformation( Rectangle( Point( aPos.X, aPos.Y ), Size( 
aSize.Width, aSize.Height ) ), nXmlNamespace, bFlipH, bFlipV, 
OOX_DRAWINGML_EXPORT_ROTATE_CLOCKWISIFY(nRotation), bIsGroupShape );
 }
 
 void DrawingML::WriteRunProperties( const Reference< XPropertySet >& rRun, 
bool bIsField, sal_Int32 nElement, bool bCheckDirect,
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 1d4f4a20a217..3391ae3d1ec1 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -494,13 +494,32 @@ ShapeExport& ShapeExport::WriteOpenPolyPolygonShape( 
const Reference< XShape >&
 ShapeExport& ShapeExport::WriteGroupShape(const 
uno::Reference<drawing::XShape>& xShape)
 {
     FSHelperPtr pFS = GetFS();
-    bool bToplevel = !m_xParent.is();
-    if (!bToplevel)
-        mnXmlNamespace = XML_wpg;
-    pFS->startElementNS(mnXmlNamespace, (bToplevel ? XML_wgp : XML_grpSp), 
FSEND);
+
+    sal_Int32 nGroupShapeToken = XML_grpSp;
+    if (GetDocumentType() == DOCUMENT_DOCX)
+    {
+        if (!m_xParent.is())
+            nGroupShapeToken = XML_wgp; // toplevel
+        else
+            mnXmlNamespace = XML_wpg;
+    }
+
+    pFS->startElementNS(mnXmlNamespace, nGroupShapeToken, FSEND);
 
     // non visual properties
-    pFS->singleElementNS(mnXmlNamespace, XML_cNvGrpSpPr, FSEND);
+    if (GetDocumentType() != DOCUMENT_DOCX)
+    {
+        pFS->startElementNS(mnXmlNamespace, XML_nvGrpSpPr, FSEND);
+        pFS->singleElementNS(mnXmlNamespace, XML_cNvPr,
+                XML_id, I32S(GetNewShapeID(xShape)),
+                XML_name, IDS(Group),
+                FSEND);
+        pFS->singleElementNS(mnXmlNamespace, XML_cNvGrpSpPr, FSEND);
+        WriteNonVisualProperties(xShape );
+        pFS->endElementNS(mnXmlNamespace, XML_nvGrpSpPr);
+    }
+    else
+        pFS->singleElementNS(mnXmlNamespace, XML_cNvGrpSpPr, FSEND);
 
     // visual properties
     pFS->startElementNS(mnXmlNamespace, XML_grpSpPr, FSEND);
@@ -516,17 +535,20 @@ ShapeExport& ShapeExport::WriteGroupShape(const 
uno::Reference<drawing::XShape>&
         sal_Int32 nSavedNamespace = mnXmlNamespace;
 
         uno::Reference<lang::XServiceInfo> xServiceInfo(xChild, 
uno::UNO_QUERY_THROW);
-        if 
(xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
-            mnXmlNamespace = XML_pic;
-        else
-            mnXmlNamespace = XML_wps;
+        if (GetDocumentType() == DOCUMENT_DOCX)
+        {
+            if 
(xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
+                mnXmlNamespace = XML_pic;
+            else
+                mnXmlNamespace = XML_wps;
+        }
         WriteShape(xChild);
 
         mnXmlNamespace = nSavedNamespace;
     }
     m_xParent = xParent;
 
-    pFS->endElementNS(mnXmlNamespace, (bToplevel ? XML_wgp : XML_grpSp));
+    pFS->endElementNS(mnXmlNamespace, nGroupShapeToken);
     return *this;
 }
 
@@ -1373,7 +1395,7 @@ ShapeExport& ShapeExport::WriteRectangleShape( const 
Reference< XShape >& xShape
 typedef ShapeExport& (ShapeExport::*ShapeConverter)( const Reference< XShape 
>& );
 typedef std::unordered_map< const char*, ShapeConverter, rtl::CStringHash, 
rtl::CStringEqual> NameToConvertMapType;
 
-static const NameToConvertMapType& lcl_GetConverters(DocumentType 
eDocumentType)
+static const NameToConvertMapType& lcl_GetConverters()
 {
     static bool shape_map_inited = false;
     static NameToConvertMapType shape_converters;
@@ -1389,12 +1411,13 @@ static const NameToConvertMapType& 
lcl_GetConverters(DocumentType eDocumentType)
     shape_converters[ "com.sun.star.drawing.GraphicObjectShape" ]       = 
&ShapeExport::WriteGraphicObjectShape;
     shape_converters[ "com.sun.star.drawing.LineShape" ]                = 
&ShapeExport::WriteLineShape;
     shape_converters[ "com.sun.star.drawing.OpenBezierShape" ]          = 
&ShapeExport::WriteOpenPolyPolygonShape;
-    shape_converters[ "com.sun.star.drawing.PolyPolygonShape" ]          = 
&ShapeExport::WriteClosedPolyPolygonShape;
-    shape_converters[ "com.sun.star.drawing.PolyLineShape" ]          = 
&ShapeExport::WriteClosedPolyPolygonShape;
+    shape_converters[ "com.sun.star.drawing.PolyPolygonShape" ]         = 
&ShapeExport::WriteClosedPolyPolygonShape;
+    shape_converters[ "com.sun.star.drawing.PolyLineShape" ]            = 
&ShapeExport::WriteClosedPolyPolygonShape;
     shape_converters[ "com.sun.star.drawing.RectangleShape" ]           = 
&ShapeExport::WriteRectangleShape;
     shape_converters[ "com.sun.star.drawing.OLE2Shape" ]                = 
&ShapeExport::WriteOLE2Shape;
     shape_converters[ "com.sun.star.drawing.TableShape" ]               = 
&ShapeExport::WriteTableShape;
     shape_converters[ "com.sun.star.drawing.TextShape" ]                = 
&ShapeExport::WriteTextShape;
+    shape_converters[ "com.sun.star.drawing.GroupShape" ]               = 
&ShapeExport::WriteGroupShape;
 
     shape_converters[ "com.sun.star.presentation.GraphicObjectShape" ]  = 
&ShapeExport::WriteGraphicObjectShape;
     shape_converters[ "com.sun.star.presentation.OLE2Shape" ]           = 
&ShapeExport::WriteOLE2Shape;
@@ -1408,8 +1431,6 @@ static const NameToConvertMapType& 
lcl_GetConverters(DocumentType eDocumentType)
     shape_converters[ "com.sun.star.presentation.OutlinerShape" ]       = 
&ShapeExport::WriteTextShape;
     shape_converters[ "com.sun.star.presentation.SlideNumberShape" ]    = 
&ShapeExport::WriteTextShape;
     shape_converters[ "com.sun.star.presentation.TitleTextShape" ]      = 
&ShapeExport::WriteTextShape;
-    if (eDocumentType == DOCUMENT_DOCX)
-        shape_converters[ "com.sun.star.drawing.GroupShape" ] = 
&ShapeExport::WriteGroupShape;
     shape_map_inited = true;
 
     return shape_converters;
@@ -1419,8 +1440,8 @@ ShapeExport& ShapeExport::WriteShape( const Reference< 
XShape >& xShape )
 {
     OUString sShapeType = xShape->getShapeType();
     SAL_INFO("oox.shape", "write shape: " << sShapeType);
-    NameToConvertMapType::const_iterator aConverter = 
lcl_GetConverters(GetDocumentType()).find( USS( sShapeType ) );
-    if( aConverter == lcl_GetConverters(GetDocumentType()).end() )
+    NameToConvertMapType::const_iterator aConverter = 
lcl_GetConverters().find(USS(sShapeType));
+    if (aConverter == lcl_GetConverters().end())
     {
         SAL_INFO("oox.shape", "unknown shape");
         return WriteUnknownShape( xShape );
diff --git a/sd/qa/unit/data/pptx/tdf111884.pptx 
b/sd/qa/unit/data/pptx/tdf111884.pptx
new file mode 100644
index 000000000000..9d08b668defa
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf111884.pptx differ
diff --git a/sd/qa/unit/export-tests-ooxml1.cxx 
b/sd/qa/unit/export-tests-ooxml1.cxx
index 2fc233bf836a..3daf058daa9c 100644
--- a/sd/qa/unit/export-tests-ooxml1.cxx
+++ b/sd/qa/unit/export-tests-ooxml1.cxx
@@ -104,6 +104,7 @@ public:
     void testBulletCharAndFont();
     void testBulletMarginAndIndentation();
     void testParaMarginAndindentation();
+    void testTdf111884();
 
     CPPUNIT_TEST_SUITE(SdOOXMLExportTest1);
 
@@ -131,6 +132,7 @@ public:
     CPPUNIT_TEST(testBulletCharAndFont);
     CPPUNIT_TEST(testBulletMarginAndIndentation);
     CPPUNIT_TEST(testParaMarginAndindentation);
+    CPPUNIT_TEST(testTdf111884);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -221,20 +223,26 @@ void SdOOXMLExportTest1::testBnc870233_2()
 
     // First smart art has blue font color (direct formatting)
     {
-        const SdrTextObj *pObj = dynamic_cast<SdrTextObj *>( pPage->GetObj( 0 
) );
-        checkFontAttributes<Color, SvxColorItem>( pObj, Color(0x0000ff) );
+        const SdrObjGroup *pObjGroup = dynamic_cast<SdrObjGroup 
*>(pPage->GetObj(0));
+        CPPUNIT_ASSERT(pObjGroup);
+        const SdrTextObj *pObj = dynamic_cast<SdrTextObj 
*>(pObjGroup->GetSubList()->GetObj(0));
+        checkFontAttributes<Color, SvxColorItem>(pObj, Color(0x0000ff));
     }
 
     // Second smart art has "dk2" font color (style)
     {
-        const SdrTextObj *pObj = dynamic_cast<SdrTextObj *>( pPage->GetObj( 1 
) );
+        const SdrObjGroup *pObjGroup = dynamic_cast<SdrObjGroup 
*>(pPage->GetObj(2)); // FIXME should be 1, smartart import creates an 
additional empty group for some reason
+        CPPUNIT_ASSERT(pObjGroup);
+        const SdrTextObj *pObj = dynamic_cast<SdrTextObj 
*>(pObjGroup->GetSubList()->GetObj(0));
         checkFontAttributes<Color, SvxColorItem>( pObj, Color(0x1F497D) );
     }
 
     // Third smart art has white font color (style)
     {
-        const SdrTextObj *pObj = dynamic_cast<SdrTextObj *>( pPage->GetObj( 2 
) );
-        checkFontAttributes<Color, SvxColorItem>( pObj, Color(0xffffff) );
+        const SdrObjGroup *pObjGroup = dynamic_cast<SdrObjGroup 
*>(pPage->GetObj(4)); // FIXME should be 2, smartart import creates an 
additional empty group for some reason
+        CPPUNIT_ASSERT(pObjGroup);
+        const SdrTextObj *pObj = dynamic_cast<SdrTextObj 
*>(pObjGroup->GetSubList()->GetObj(0));
+        checkFontAttributes<Color, SvxColorItem>(pObj, Color(0xffffff));
     }
 
     xDocShRef->DoClose();
@@ -366,12 +374,14 @@ void SdOOXMLExportTest1::testBnc880763()
 
     // Check z-order of the two shapes, use background color to identify them
     // First object in the background has blue background color
-    const SdrObject *pObj = dynamic_cast<SdrObject *>( pPage->GetObj( 0 ) );
+    const SdrObjGroup *pObjGroup = dynamic_cast<SdrObjGroup 
*>(pPage->GetObj(0));
+    CPPUNIT_ASSERT(pObjGroup);
+    const SdrObject *pObj = dynamic_cast<SdrObject 
*>(pObjGroup->GetSubList()->GetObj(0));
     CPPUNIT_ASSERT_MESSAGE( "no object", pObj != nullptr);
     CPPUNIT_ASSERT_EQUAL( sal_uInt32(0x0000ff),(static_cast< const XColorItem& 
>(pObj->GetMergedItem(XATTR_FILLCOLOR))).GetColorValue().GetColor());
 
     // Second object at the front has green background color
-    pObj = dynamic_cast<SdrObject *>( pPage->GetObj( 1 ) );
+    pObj = dynamic_cast<SdrObject *>(pPage->GetObj(2)); // FIXME should be 1, 
smartart import creates an additional empty group for some reason
     CPPUNIT_ASSERT_MESSAGE( "no object", pObj != nullptr);
     CPPUNIT_ASSERT_EQUAL( sal_uInt32(0x00ff00),(static_cast< const XColorItem& 
>(pObj->GetMergedItem(XATTR_FILLCOLOR))).GetColorValue().GetColor());
 
@@ -386,7 +396,9 @@ void SdOOXMLExportTest1::testBnc862510_5()
     const SdrPage *pPage = GetPage( 1, xDocShRef );
 
     // Same as testBnc870237, but here we check the horizontal spacing
-    const SdrObject* pObj = dynamic_cast<SdrObject*>( pPage->GetObj( 1 ) );
+    const SdrObjGroup *pObjGroup = dynamic_cast<SdrObjGroup 
*>(pPage->GetObj(0));
+    CPPUNIT_ASSERT(pObjGroup);
+    const SdrObject* pObj = 
dynamic_cast<SdrObject*>(pObjGroup->GetSubList()->GetObj(1));
     CPPUNIT_ASSERT_MESSAGE( "no object", pObj != nullptr);
     CPPUNIT_ASSERT_EQUAL( sal_Int32(0), (static_cast< const SdrMetricItem& 
>(pObj->GetMergedItem(SDRATTR_TEXT_UPPERDIST))).GetValue());
     CPPUNIT_ASSERT_EQUAL( sal_Int32(0), (static_cast< const SdrMetricItem& 
>(pObj->GetMergedItem(SDRATTR_TEXT_LOWERDIST))).GetValue());
@@ -779,6 +791,21 @@ void SdOOXMLExportTest1::testTableCellBorder()
     xDocShRef->DoClose();
 }
 
+void SdOOXMLExportTest1::testTdf111884()
+{
+    ::sd::DrawDocShellRef xDocShRef = 
loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf111884.pptx"), 
PPTX);
+    xDocShRef = saveAndReload(xDocShRef.get(), PPTX);
+
+    const SdrPage *pPage = GetPage(1, xDocShRef);
+    SdrObject const* pShape = pPage->GetObj(2);
+    CPPUNIT_ASSERT_MESSAGE("no shape", pShape != nullptr);
+
+    // must be a group shape
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(OBJ_GRUP), 
pShape->GetObjIdentifier());
+
+    xDocShRef->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest1);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx 
b/sd/source/filter/eppt/pptx-epptooxml.cxx
index 1f63910e6722..769f013126bd 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -296,14 +296,7 @@ ShapeExport& PowerPointShapeExport::WriteUnknownShape( 
const Reference< XShape >
 
     SAL_INFO("sd.eppt", "shape(unknown): " << USS(sShapeType));
 
-    if ( sShapeType == "com.sun.star.drawing.GroupShape" )
-    {
-        Reference< XIndexAccess > rXIndexAccess( xShape, UNO_QUERY );
-
-        mrExport.EnterGroup( rXIndexAccess );
-        SAL_INFO("sd.eppt", "enter group");
-    }
-    else if ( sShapeType == "com.sun.star.drawing.PageShape" )
+    if (sShapeType == "com.sun.star.presentation.PageShape")
     {
         WritePageShape( xShape, mePageType, mrExport.GetPresObj() );
     }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to