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