summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Holesovsky <kendy@collabora.com>2017-08-31 18:32:58 +0200
committerJan Holesovsky <kendy@collabora.com>2017-09-06 19:30:29 +0200
commit42c70214dc3000b609fa4ee8063b36bd9a2bdbe1 (patch)
treea1cd24019d4eb44d5930e9604281a09b9e45da8a
parente36e716e877c707c991db7bad87724c4a20af27c (diff)
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 <ci@libreoffice.org> Reviewed-by: Jan Holesovsky <kendy@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/42021 Tested-by: Jan Holesovsky <kendy@collabora.com>
-rw-r--r--include/oox/export/drawingml.hxx4
-rw-r--r--oox/source/export/drawingml.cxx18
-rw-r--r--oox/source/export/shapes.cxx55
-rw-r--r--sd/qa/unit/data/pptx/tdf111884.pptxbin0 -> 30898 bytes
-rw-r--r--sd/qa/unit/export-tests-ooxml1.cxx43
-rw-r--r--sd/source/filter/eppt/pptx-epptooxml.cxx9
6 files changed, 90 insertions, 39 deletions
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
--- /dev/null
+++ b/sd/qa/unit/data/pptx/tdf111884.pptx
Binary files 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() );
}