include/oox/drawingml/shape.hxx | 2 oox/source/core/xmlfilterbase.cxx | 1 oox/source/drawingml/connectorshapecontext.cxx | 8 ++ oox/source/drawingml/shape.cxx | 4 + oox/source/drawingml/shapecontext.cxx | 8 ++ oox/source/drawingml/shapegroupcontext.cxx | 8 ++ oox/source/export/shapes.cxx | 73 +++++++++++++++++---- oox/source/ppt/pptshapegroupcontext.cxx | 8 ++ sd/qa/unit/data/pptx/tdf141058-1.pptx |binary sd/qa/unit/export-tests.cxx | 86 +++++++++++++++++++++++++ sw/qa/extras/globalfilter/globalfilter.cxx | 17 ++++ sw/source/filter/ww8/docxattributeoutput.cxx | 15 ---- sw/source/filter/ww8/docxsdrexport.cxx | 23 ++++++ sw/source/filter/ww8/docxsdrexport.hxx | 5 + 14 files changed, 229 insertions(+), 29 deletions(-)
New commits: commit e751d59264c369cfc342dab5f0759be12341d306 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Thu Jul 6 16:57:08 2023 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Thu Jul 6 20:28:40 2023 +0200 tdf#141058 oox,sw: OOXML import/export of decorative on shapes Also add a test for PPTX (using the oox filters), and add a SdrObject to the testTdf143311 for DOCX (using the writerfilter/docxsdrexport). Change-Id: Iccee46c0d30316c33c0947b117e2604c96fa0182 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154137 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx index 72ce51ef6476..ccf477bef805 100644 --- a/include/oox/drawingml/shape.hxx +++ b/include/oox/drawingml/shape.hxx @@ -174,6 +174,7 @@ public: void setId( const OUString& rId ) { msId = rId; } const OUString& getId() const { return msId; } void setDescription( const OUString& rDescr ) { msDescription = rDescr; } + void setDecorative(bool const isDecorative) { m_isDecorative = isDecorative; } void setHidden( bool bHidden ) { mbHidden = bHidden; } void setHiddenMasterShape( bool bHiddenMasterShape ) { mbHiddenMasterShape = bHiddenMasterShape; } void setLocked( bool bLocked ) { mbLocked = bLocked; } @@ -356,6 +357,7 @@ protected: OUString msInternalName; // used by diagram; not displayed in UI OUString msId; OUString msDescription; + bool m_isDecorative = false; sal_Int32 mnSubType; // if this type is not zero, then the shape is a placeholder std::optional< sal_Int32 > moSubTypeIndex; diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index c2911a756047..0c95980accd4 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -148,6 +148,7 @@ const Sequence< beans::Pair< OUString, sal_Int32 > >& NamespaceIds() NMSP_c15}, {"http://schemas.microsoft.com/office/spreadsheetml/2015/revision2", NMSP_xr2}, + {"http://schemas.microsoft.com/office/drawing/2017/decorative", NMSP_adec}, }; return SINGLETON; }; diff --git a/oox/source/drawingml/connectorshapecontext.cxx b/oox/source/drawingml/connectorshapecontext.cxx index 8ea0bcca6965..018ca95c648d 100644 --- a/oox/source/drawingml/connectorshapecontext.cxx +++ b/oox/source/drawingml/connectorshapecontext.cxx @@ -69,6 +69,14 @@ ConnectorShapePropertiesContext::onCreateContext(sal_Int32 aElementToken, { switch (getBaseToken(aElementToken)) { + case XML_extLst: + case XML_ext: + break; + case XML_decorative: + { + mpConnectorShapePtr->setDecorative(rAttribs.getBool(XML_val, false)); + break; + } case XML_cNvPr: mpConnectorShapePtr->setId(rAttribs.getStringDefaulted(XML_id)); mpConnectorShapePtr->setName(rAttribs.getStringDefaulted(XML_name)); diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 040a632563cc..0fca9c0e1ac3 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -1144,6 +1144,10 @@ Reference< XShape > const & Shape::createAndInsert( { xSet->setPropertyValue( "Description", Any( msDescription ) ); } + if (m_isDecorative) + { + xSet->setPropertyValue("Decorative", Any(m_isDecorative)); + } if (aServiceName != "com.sun.star.text.TextFrame") rxShapes->add( mxShape ); diff --git a/oox/source/drawingml/shapecontext.cxx b/oox/source/drawingml/shapecontext.cxx index d14864ede331..73fdab79508e 100644 --- a/oox/source/drawingml/shapecontext.cxx +++ b/oox/source/drawingml/shapecontext.cxx @@ -66,6 +66,14 @@ ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 aElementToken, const // nvSpPr CT_ShapeNonVisual begin // case XML_drElemPr: // break; + case XML_extLst: + case XML_ext: + break; + case XML_decorative: + { + mpShapePtr->setDecorative(rAttribs.getBool(XML_val, false)); + } + break; case XML_cNvPr: { mpShapePtr->setHidden( rAttribs.getBool( XML_hidden, false ) ); diff --git a/oox/source/drawingml/shapegroupcontext.cxx b/oox/source/drawingml/shapegroupcontext.cxx index 02ce5917e682..d810b0448b9a 100644 --- a/oox/source/drawingml/shapegroupcontext.cxx +++ b/oox/source/drawingml/shapegroupcontext.cxx @@ -58,6 +58,14 @@ ContextHandlerRef ShapeGroupContext::onCreateContext( sal_Int32 aElementToken, c { switch( getBaseToken( aElementToken ) ) { + case XML_extLst: + case XML_ext: + break; + case XML_decorative: + { + mpGroupShapePtr->setDecorative(rAttribs.getBool(XML_val, false)); + } + break; case XML_cNvPr: { mpGroupShapePtr->setHidden( rAttribs.getBool( XML_hidden, false ) ); diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index fc702c1c3a22..78614b7efbcc 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -394,6 +394,24 @@ bool ShapeExport::NonEmptyText( const Reference< XInterface >& xIface ) return IsNonEmptySimpleText(xIface); } +static void AddExtLst(FSHelperPtr const& pFS, Reference<XPropertySet> const& xShape) +{ + if (xShape->getPropertySetInfo()->hasPropertyByName("Decorative") + && xShape->getPropertyValue("Decorative").get<bool>()) + { + pFS->startElementNS(XML_a, XML_extLst); +// FSNS(XML_xmlns, XML_a), GetExport().GetFilter().getNamespaceURL(OOX_NS(dml))); + pFS->startElementNS(XML_a, XML_ext, + // MSO uses this "URI" which is obviously not a URI + XML_uri, "{C183D7F6-B498-43B3-948B-1728B52AA6E4}"); + pFS->singleElementNS(XML_adec, XML_decorative, + FSNS(XML_xmlns, XML_adec), "http://schemas.microsoft.com/office/drawing/2017/decorative", + XML_val, "1"); + pFS->endElementNS(XML_a, XML_ext); + pFS->endElementNS(XML_a, XML_extLst); + } +} + ShapeExport& ShapeExport::WritePolyPolygonShape( const Reference< XShape >& xShape, const bool bClosed ) { SAL_INFO("oox.shape", "write polypolygon shape"); @@ -419,13 +437,16 @@ ShapeExport& ShapeExport::WritePolyPolygonShape( const Reference< XShape >& xSha SAL_INFO("oox.shape", "size: " << size.Width << " x " << size.Height); #endif + Reference<XPropertySet> const xProps(xShape, UNO_QUERY); // non visual shape properties if (GetDocumentType() != DOCUMENT_DOCX || mbUserShapes) { pFS->startElementNS(mnXmlNamespace, XML_nvSpPr); - pFS->singleElementNS( mnXmlNamespace, XML_cNvPr, + pFS->startElementNS(mnXmlNamespace, XML_cNvPr, XML_id, OString::number(GetNewShapeID(xShape)), XML_name, GetShapeName(xShape)); + AddExtLst(pFS, xProps); + pFS->endElementNS(mnXmlNamespace, XML_cNvPr); } pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr); if (GetDocumentType() != DOCUMENT_DOCX || mbUserShapes) @@ -438,7 +459,6 @@ ShapeExport& ShapeExport::WritePolyPolygonShape( const Reference< XShape >& xSha pFS->startElementNS(mnXmlNamespace, XML_spPr); WriteTransformation( xShape, aRect, XML_a ); WritePolyPolygon(xShape, bClosed); - Reference< XPropertySet > xProps( xShape, UNO_QUERY ); if( xProps.is() ) { if( bClosed ) WriteFill(xProps, aSize); @@ -484,9 +504,12 @@ ShapeExport& ShapeExport::WriteGroupShape(const uno::Reference<drawing::XShape>& if (GetDocumentType() != DOCUMENT_DOCX || mbUserShapes) { pFS->startElementNS(mnXmlNamespace, XML_nvGrpSpPr); - pFS->singleElementNS(mnXmlNamespace, XML_cNvPr, + pFS->startElementNS(mnXmlNamespace, XML_cNvPr, XML_id, OString::number(GetNewShapeID(xShape)), XML_name, GetShapeName(xShape)); + uno::Reference<beans::XPropertySet> const xShapeProps(xShape, uno::UNO_QUERY_THROW); + AddExtLst(pFS, xShapeProps); + pFS->endElementNS(mnXmlNamespace, XML_cNvPr); pFS->singleElementNS(mnXmlNamespace, XML_cNvGrpSpPr); WriteNonVisualProperties(xShape ); pFS->endElementNS(mnXmlNamespace, XML_nvGrpSpPr); @@ -894,6 +917,7 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape ) mpFS->singleElementNS(XML_a, XML_hlinkClick, FSNS(XML_r, XML_id), sRelId, XML_action, "ppaction://hlinksldjump"); } + AddExtLst(pFS, rXPropSet); pFS->endElementNS(mnXmlNamespace, XML_cNvPr); pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr); WriteNonVisualProperties( xShape ); @@ -923,6 +947,7 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape ) mpFS->singleElementNS(XML_a, XML_hlinkClick, FSNS(XML_r, XML_id), sRelId); } } + AddExtLst(pFS, rXPropSet); pFS->endElementNS(mnXmlNamespace, XML_cNvPr); } pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr); @@ -1151,13 +1176,16 @@ ShapeExport& ShapeExport::WriteEllipseShape( const Reference< XShape >& xShape ) // TODO: connector ? + Reference<XPropertySet> const xProps(xShape, UNO_QUERY); // non visual shape properties if (GetDocumentType() != DOCUMENT_DOCX || mbUserShapes) { pFS->startElementNS(mnXmlNamespace, XML_nvSpPr); - pFS->singleElementNS( mnXmlNamespace, XML_cNvPr, + pFS->startElementNS(mnXmlNamespace, XML_cNvPr, XML_id, OString::number(GetNewShapeID(xShape)), XML_name, GetShapeName(xShape)); + AddExtLst(pFS, xProps); + pFS->endElementNS(mnXmlNamespace, XML_cNvPr); pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr ); WriteNonVisualProperties( xShape ); pFS->endElementNS( mnXmlNamespace, XML_nvSpPr ); @@ -1165,7 +1193,6 @@ ShapeExport& ShapeExport::WriteEllipseShape( const Reference< XShape >& xShape ) else pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr); - Reference< XPropertySet > xProps( xShape, UNO_QUERY ); CircleKind eCircleKind(CircleKind_FULL); if (xProps.is()) xProps->getPropertyValue("CircleKind" ) >>= eCircleKind; @@ -1369,6 +1396,7 @@ void ShapeExport::WriteGraphicObjectShapePart( const Reference< XShape >& xShape mpFS->singleElementNS(XML_a, XML_hlinkClick, FSNS(XML_r, XML_id), sRelId, XML_action, "ppaction://hlinksldjump"); } + AddExtLst(pFS, xShapeProps); pFS->endElementNS(mnXmlNamespace, XML_cNvPr); pFS->singleElementNS(mnXmlNamespace, XML_cNvPicPr @@ -1822,9 +1850,11 @@ ShapeExport& ShapeExport::WriteConnectorShape( const Reference< XShape >& xShape { // non visual shape properties pFS->startElementNS(mnXmlNamespace, XML_nvCxnSpPr); - pFS->singleElementNS(mnXmlNamespace, XML_cNvPr, + pFS->startElementNS(mnXmlNamespace, XML_cNvPr, XML_id, OString::number(GetNewShapeID(xShape)), XML_name, GetShapeName(xShape)); + AddExtLst(pFS, rXPropSet); + pFS->endElementNS(mnXmlNamespace, XML_cNvPr); // non visual connector shape drawing properties pFS->startElementNS(mnXmlNamespace, XML_cNvCxnSpPr); @@ -1881,13 +1911,16 @@ ShapeExport& ShapeExport::WriteLineShape( const Reference< XShape >& xShape ) bFlipV = ( rPoly[ 0 ].Y() > rPoly[ 1 ].Y() ); } + Reference<XPropertySet> const xShapeProps(xShape, UNO_QUERY); // non visual shape properties if (GetDocumentType() != DOCUMENT_DOCX || mbUserShapes) { pFS->startElementNS(mnXmlNamespace, XML_nvSpPr); - pFS->singleElementNS( mnXmlNamespace, XML_cNvPr, + pFS->startElementNS(mnXmlNamespace, XML_cNvPr, XML_id, OString::number(GetNewShapeID(xShape)), XML_name, GetShapeName(xShape)); + AddExtLst(pFS, xShapeProps); + pFS->endElementNS(mnXmlNamespace, XML_cNvPr); } pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr ); if (GetDocumentType() != DOCUMENT_DOCX || mbUserShapes) @@ -1900,7 +1933,6 @@ ShapeExport& ShapeExport::WriteLineShape( const Reference< XShape >& xShape ) pFS->startElementNS(mnXmlNamespace, XML_spPr); WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, true); WritePresetShape( "line" ); - Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY ); if( xShapeProps.is() ) WriteOutline( xShapeProps ); pFS->endElementNS( mnXmlNamespace, XML_spPr ); @@ -1920,9 +1952,14 @@ ShapeExport& ShapeExport::WriteLineShape( const Reference< XShape >& xShape ) ShapeExport& ShapeExport::WriteNonVisualDrawingProperties( const Reference< XShape >& xShape, const char* pName ) { - GetFS()->singleElementNS( mnXmlNamespace, XML_cNvPr, + FSHelperPtr pFS = GetFS(); + + Reference<XPropertySet> const xShapeProps(xShape, UNO_QUERY); + pFS->startElementNS(mnXmlNamespace, XML_cNvPr, XML_id, OString::number(GetNewShapeID(xShape)), XML_name, pName ); + AddExtLst(pFS, xShapeProps); + pFS->endElementNS(mnXmlNamespace, XML_cNvPr); return *this; } @@ -1960,9 +1997,11 @@ ShapeExport& ShapeExport::WriteRectangleShape( const Reference< XShape >& xShape if (GetDocumentType() == DOCUMENT_DOCX && !mbUserShapes) pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr); pFS->startElementNS(mnXmlNamespace, XML_nvSpPr); - pFS->singleElementNS( mnXmlNamespace, XML_cNvPr, + pFS->startElementNS(mnXmlNamespace, XML_cNvPr, XML_id, OString::number(GetNewShapeID(xShape)), XML_name, GetShapeName(xShape)); + AddExtLst(pFS, xShapeProps); + pFS->endElementNS(mnXmlNamespace, XML_cNvPr); pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr); WriteNonVisualProperties( xShape ); pFS->endElementNS( mnXmlNamespace, XML_nvSpPr ); @@ -2425,9 +2464,12 @@ ShapeExport& ShapeExport::WriteTableShape( const Reference< XShape >& xShape ) pFS->startElementNS(mnXmlNamespace, XML_nvGraphicFramePr); - pFS->singleElementNS( mnXmlNamespace, XML_cNvPr, + Reference<XPropertySet> const xShapeProps(xShape, UNO_QUERY); + pFS->startElementNS(mnXmlNamespace, XML_cNvPr, XML_id, OString::number(GetNewShapeID(xShape)), XML_name, GetShapeName(xShape)); + AddExtLst(pFS, xShapeProps); + pFS->endElementNS(mnXmlNamespace, XML_cNvPr); pFS->singleElementNS(mnXmlNamespace, XML_cNvGraphicFramePr); @@ -2470,6 +2512,7 @@ ShapeExport& ShapeExport::WriteTextShape( const Reference< XShape >& xShape ) mpFS->singleElementNS(XML_a, XML_hlinkClick, FSNS(XML_r, XML_id), sRelId); } + AddExtLst(pFS, xShapeProps); pFS->endElementNS(mnXmlNamespace, XML_cNvPr); } pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr, XML_txBox, "1"); @@ -2517,9 +2560,11 @@ void ShapeExport::WriteMathShape(Reference<XShape> const& xShape) XML_Requires, "a14"); mpFS->startElementNS(mnXmlNamespace, XML_sp); mpFS->startElementNS(mnXmlNamespace, XML_nvSpPr); - mpFS->singleElementNS(mnXmlNamespace, XML_cNvPr, + mpFS->startElementNS(mnXmlNamespace, XML_cNvPr, XML_id, OString::number(GetNewShapeID(xShape)), XML_name, GetShapeName(xShape)); + AddExtLst(mpFS, xPropSet); + mpFS->endElementNS(mnXmlNamespace, XML_cNvPr); mpFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr, XML_txBox, "1"); mpFS->singleElementNS(mnXmlNamespace, XML_nvPr); mpFS->endElementNS(mnXmlNamespace, XML_nvSpPr); @@ -2720,9 +2765,11 @@ ShapeExport& ShapeExport::WriteOLE2Shape( const Reference< XShape >& xShape ) mpFS->startElementNS(mnXmlNamespace, XML_nvGraphicFramePr); - mpFS->singleElementNS( mnXmlNamespace, XML_cNvPr, + mpFS->startElementNS(mnXmlNamespace, XML_cNvPr, XML_id, OString::number(GetNewShapeID(xShape)), XML_name, GetShapeName(xShape)); + AddExtLst(mpFS, xPropSet); + mpFS->endElementNS(mnXmlNamespace, XML_cNvPr); mpFS->singleElementNS(mnXmlNamespace, XML_cNvGraphicFramePr); diff --git a/oox/source/ppt/pptshapegroupcontext.cxx b/oox/source/ppt/pptshapegroupcontext.cxx index dcce466fefd2..49a5f5ce4ba6 100644 --- a/oox/source/ppt/pptshapegroupcontext.cxx +++ b/oox/source/ppt/pptshapegroupcontext.cxx @@ -65,6 +65,14 @@ ContextHandlerRef PPTShapeGroupContext::onCreateContext( sal_Int32 aElementToken switch( aElementToken ) { + case OOX_TOKEN(dml, extLst): + case OOX_TOKEN(dml, ext): + break; + case OOX_TOKEN(adec, decorative): + { + mpGroupShapePtr->setDecorative(rAttribs.getBool(XML_val, false)); + } + break; case PPT_TOKEN( cNvPr ): { // don't override SmartArt properties for embedded drawing's spTree diff --git a/sd/qa/unit/data/pptx/tdf141058-1.pptx b/sd/qa/unit/data/pptx/tdf141058-1.pptx new file mode 100644 index 000000000000..a93bf8824292 Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf141058-1.pptx differ diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx index aee7e6724e32..61f6736fc33f 100644 --- a/sd/qa/unit/export-tests.cxx +++ b/sd/qa/unit/export-tests.cxx @@ -199,6 +199,92 @@ CPPUNIT_TEST_FIXTURE(SdExportTest, testTransparentBackground) checkFontAttributes<Color, SvxColorItem>(pObj2, COL_YELLOW, EE_CHAR_BKGCOLOR); } +CPPUNIT_TEST_FIXTURE(SdExportTest, testDecorative) +{ + createSdImpressDoc("pptx/tdf141058-1.pptx"); + + auto doTest = [this](OString const test) { + ::std::set<OString> const decorative = { + "Picture 6", + "Rectangle 7", + "Group 24", + "Connector: Elbow 9", + "Connector: Elbow 11", + "Connector: Elbow 14", + "Connector: Elbow 17", + "Straight Arrow Connector 21", + "Straight Arrow Connector 22", + "Straight Arrow Connector 23", + }; + + uno::Reference<drawing::XDrawPage> const xPage(getPage(0)); + CPPUNIT_ASSERT_EQUAL_MESSAGE(test.getStr(), sal_Int32(5), xPage->getCount()); + auto nDecorative(0); + auto nShapes(0); + auto nInnerDecorative(0); + auto nInnerShapes(0); + for (auto i = xPage->getCount(); i != 0; --i) + { + uno::Reference<beans::XPropertySet> xShape(getShape(i - 1, xPage)); + uno::Reference<container::XNamed> xNamed(xShape, uno::UNO_QUERY); + OString const name(OUStringToOString(xNamed->getName(), RTL_TEXTENCODING_UTF8)); + if (decorative.find(name) != decorative.end()) + { + CPPUNIT_ASSERT_MESSAGE(OString(test + name).getStr(), + xShape->getPropertyValue("Decorative").get<bool>()); + ++nDecorative; + } + else + { + CPPUNIT_ASSERT_MESSAGE(OString(test + name).getStr(), + !xShape->getPropertyValue("Decorative").get<bool>()); + ++nShapes; + } + uno::Reference<drawing::XShapes> const xShapes(xShape, uno::UNO_QUERY); + if (xShapes.is()) + { + for (auto j = xShapes->getCount(); j != 0; --j) + { + uno::Reference<beans::XPropertySet> xInnerShape(xShapes->getByIndex(i - 1), + uno::UNO_QUERY); + uno::Reference<container::XNamed> xInnerNamed(xInnerShape, uno::UNO_QUERY); + OString const innerName( + OUStringToOString(xInnerNamed->getName(), RTL_TEXTENCODING_UTF8)); + if (decorative.find(innerName) != decorative.end()) + { + CPPUNIT_ASSERT_MESSAGE( + OString(test + innerName).getStr(), + xInnerShape->getPropertyValue("Decorative").get<bool>()); + ++nInnerDecorative; + } + else + { + CPPUNIT_ASSERT_MESSAGE( + OString(test + innerName).getStr(), + !xInnerShape->getPropertyValue("Decorative").get<bool>()); + ++nInnerShapes; + } + } + } + } + CPPUNIT_ASSERT_EQUAL_MESSAGE(test.getStr(), static_cast<decltype(nDecorative)>(3), + nDecorative); + CPPUNIT_ASSERT_EQUAL_MESSAGE(test.getStr(), static_cast<decltype(nShapes)>(2), nShapes); + CPPUNIT_ASSERT_EQUAL_MESSAGE(test.getStr(), static_cast<decltype(nInnerDecorative)>(7), + nInnerDecorative); + CPPUNIT_ASSERT_EQUAL_MESSAGE(test.getStr(), static_cast<decltype(nInnerShapes)>(16), + nInnerShapes); + }; + + doTest("initial pptx load: "); + + saveAndReload("Impress Office Open XML"); + doTest("reload OOXML: "); + + saveAndReload("impress8"); + doTest("reload ODF: "); +} + CPPUNIT_TEST_FIXTURE(SdExportTest, testTdf142716) { createSdImpressDoc("pptx/tdf142716.pptx"); diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx index 37f112dc624f..0c7415ddabe6 100644 --- a/sw/qa/extras/globalfilter/globalfilter.cxx +++ b/sw/qa/extras/globalfilter/globalfilter.cxx @@ -1657,9 +1657,21 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf143311) { createSwDoc("tdf143311-1.docx"); CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(getShape(1), "Decorative")); + { + // add another one that's a SdrObject + uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XShape> xShape( + xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY); + xShapeProps->setPropertyValue("Decorative", uno::Any(true)); + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage()); + xDrawPage->add(xShape); + } // check DOCX filters saveAndReload("Office Open XML Text"); CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(getShape(1), "Decorative")); + CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(getShape(2), "Decorative")); { // tdf#153925 not imported - check default and set it to test ODF filters uno::Reference<beans::XPropertySet> const xStyle(getStyles("FrameStyles")->getByName("Formula"), uno::UNO_QUERY_THROW); @@ -1669,6 +1681,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf143311) // check ODF filters saveAndReload("writer8"); CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(getShape(1), "Decorative")); + CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(getShape(2), "Decorative")); CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(getStyles("FrameStyles")->getByName("Formula"), "Decorative")); // check PDF export @@ -1754,8 +1767,8 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf143311) } CPPUNIT_ASSERT_EQUAL_MESSAGE("unclosed MCS", Default, state); CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nTagged)>(25), nTagged); // text in body - // 1 decorative image + 1 pre-existing rectangle border or something - CPPUNIT_ASSERT(nArtifacts >= 2); + // 1 decorative image + 1 decorative shape + 1 pre-existing rectangle border or something + CPPUNIT_ASSERT(nArtifacts >= 3); } void Test::testTextFormField() diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 3b095a96aea6..21e788665230 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -5266,20 +5266,7 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main", FSNS( XML_r, XML_id ), sRelId); } - - if (xShapePropSet->getPropertyValue("Decorative").get<bool>()) - { - m_pSerializer->startElementNS(XML_a, XML_extLst, - FSNS(XML_xmlns, XML_a), GetExport().GetFilter().getNamespaceURL(OOX_NS(dml))); - m_pSerializer->startElementNS(XML_a, XML_ext, - // Word uses this "URI" which is obviously not a URI - XML_uri, "{C183D7F6-B498-43B3-948B-1728B52AA6E4}"); - m_pSerializer->singleElementNS(XML_adec, XML_decorative, - FSNS(XML_xmlns, XML_adec), "http://schemas.microsoft.com/office/drawing/2017/decorative", - XML_val, "1"); - m_pSerializer->endElementNS(XML_a, XML_ext); - m_pSerializer->endElementNS(XML_a, XML_extLst); - } + AddExtLst(m_pSerializer, GetExport(), xShapePropSet); } m_pSerializer->endElementNS( XML_wp, XML_docPr ); diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index 4b3e53196a29..0c42d28fc6ad 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -1383,6 +1383,26 @@ static bool lcl_isLockedCanvas(const uno::Reference<drawing::XShape>& xShape) }); } +void AddExtLst(sax_fastparser::FSHelperPtr const& pFS, DocxExport const& rExport, + uno::Reference<beans::XPropertySet> const& xShape) +{ + if (xShape->getPropertyValue("Decorative").get<bool>()) + { + pFS->startElementNS(XML_a, XML_extLst, + // apparently for DOCX the namespace isn't declared on the root + FSNS(XML_xmlns, XML_a), + rExport.GetFilter().getNamespaceURL(OOX_NS(dml))); + pFS->startElementNS(XML_a, XML_ext, + // Word uses this "URI" which is obviously not a URI + XML_uri, "{C183D7F6-B498-43B3-948B-1728B52AA6E4}"); + pFS->singleElementNS(XML_adec, XML_decorative, FSNS(XML_xmlns, XML_adec), + "http://schemas.microsoft.com/office/drawing/2017/decorative", XML_val, + "1"); + pFS->endElementNS(XML_a, XML_ext); + pFS->endElementNS(XML_a, XML_extLst); + } +} + void DocxSdrExport::writeDMLDrawing(const SdrObject* pSdrObject, const SwFrameFormat* pFrameFormat, int nAnchorId) { @@ -1422,6 +1442,9 @@ void DocxSdrExport::writeDMLDrawing(const SdrObject* pSdrObject, const SwFrameFo FSNS(XML_xmlns, XML_a), m_pImpl->getExport().GetFilter().getNamespaceURL(OOX_NS(dml))); } + uno::Reference<beans::XPropertySet> const xShapeProps(xShape, uno::UNO_QUERY_THROW); + AddExtLst(pFS, m_pImpl->getExport(), xShapeProps); + pFS->endElementNS(XML_wp, XML_docPr); uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW); diff --git a/sw/source/filter/ww8/docxsdrexport.hxx b/sw/source/filter/ww8/docxsdrexport.hxx index 5b29cd58db34..5ad93d51ad8e 100644 --- a/sw/source/filter/ww8/docxsdrexport.hxx +++ b/sw/source/filter/ww8/docxsdrexport.hxx @@ -16,6 +16,8 @@ #include <sax/fshelper.hxx> #include <nodeoffset.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> + namespace rtl { template <typename> class Reference; @@ -99,6 +101,9 @@ public: void writeBoxItemLine(const SvxBoxItem& rBox); }; +void AddExtLst(sax_fastparser::FSHelperPtr const& pFS, DocxExport const& rExport, + css::uno::Reference<css::beans::XPropertySet> const& xShape); + #endif // INCLUDED_SW_SOURCE_FILTER_WW8_DOCXSDREXPORT_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */