diff options
-rw-r--r-- | include/svx/unoshape.hxx | 2 | ||||
-rw-r--r-- | svx/source/unodraw/unoshap4.cxx | 25 | ||||
-rw-r--r-- | xmloff/CppunitTest_xmloff_draw.mk | 3 | ||||
-rw-r--r-- | xmloff/qa/unit/data/video-snapshot.odp | bin | 0 -> 17605 bytes | |||
-rw-r--r-- | xmloff/qa/unit/draw.cxx | 50 | ||||
-rw-r--r-- | xmloff/source/draw/shapeexport.cxx | 54 | ||||
-rw-r--r-- | xmloff/source/draw/ximpshap.cxx | 14 |
7 files changed, 146 insertions, 2 deletions
diff --git a/include/svx/unoshape.hxx b/include/svx/unoshape.hxx index 923636d3b9c7..51b65e23ade9 100644 --- a/include/svx/unoshape.hxx +++ b/include/svx/unoshape.hxx @@ -858,6 +858,8 @@ private: // override these for special property handling in subcasses. Return true if property is handled virtual bool setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue ) override; virtual bool getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue ) override; + bool getPropertyStateImpl(const SfxItemPropertyMapEntry* pProperty, + css::beans::PropertyState& rState) override; OUString referer_; }; diff --git a/svx/source/unodraw/unoshap4.cxx b/svx/source/unodraw/unoshap4.cxx index 482efb826117..ae26aaabeca6 100644 --- a/svx/source/unodraw/unoshap4.cxx +++ b/svx/source/unodraw/unoshap4.cxx @@ -1071,4 +1071,29 @@ bool SvxMediaShape::getPropertyValueImpl( const OUString& rName, const SfxItemPr } } +bool SvxMediaShape::getPropertyStateImpl(const SfxItemPropertyMapEntry* pProperty, + css::beans::PropertyState& rState) +{ +#if HAVE_FEATURE_AVMEDIA + if (pProperty->nWID == SDRATTR_GRAFCROP) + { + auto pMedia = static_cast<SdrMediaObj*>(GetSdrObject()); + const avmedia::MediaItem& rItem = pMedia->getMediaProperties(); + const text::GraphicCrop& rCrop = rItem.getCrop(); + if (rCrop.Bottom > 0 || rCrop.Left > 0 || rCrop.Right > 0 || rCrop.Top > 0) + { + // The media has a crop, expose it to UNO-based export filters. + rState = beans::PropertyState_DIRECT_VALUE; + } + else + { + rState = beans::PropertyState_AMBIGUOUS_VALUE; + } + return true; + } +#endif + + return SvxShape::getPropertyStateImpl(pProperty, rState); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/CppunitTest_xmloff_draw.mk b/xmloff/CppunitTest_xmloff_draw.mk index 42c7a9526661..a503cc9f2c1d 100644 --- a/xmloff/CppunitTest_xmloff_draw.mk +++ b/xmloff/CppunitTest_xmloff_draw.mk @@ -28,6 +28,9 @@ $(eval $(call gb_CppunitTest_use_libraries,xmloff_draw, \ test \ unotest \ utl \ + avmedia \ + svxcore \ + vcl \ )) $(eval $(call gb_CppunitTest_use_sdk_api,xmloff_draw)) diff --git a/xmloff/qa/unit/data/video-snapshot.odp b/xmloff/qa/unit/data/video-snapshot.odp Binary files differnew file mode 100644 index 000000000000..ca3b7f21dc6c --- /dev/null +++ b/xmloff/qa/unit/data/video-snapshot.odp diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx index e8462ccc6181..6aab4c12a46f 100644 --- a/xmloff/qa/unit/draw.cxx +++ b/xmloff/qa/unit/draw.cxx @@ -24,6 +24,7 @@ #include <com/sun/star/util/Color.hpp> #include <com/sun/star/text/XTextRange.hpp> #include <com/sun/star/text/XTextTable.hpp> +#include <com/sun/star/text/GraphicCrop.hpp> #include <comphelper/propertyvalue.hxx> #include <comphelper/sequence.hxx> @@ -31,6 +32,9 @@ #include <unotools/tempfile.hxx> #include <unotools/ucbstreamhelper.hxx> #include <unotools/saveopt.hxx> +#include <svx/unopage.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdomedia.hxx> using namespace ::com::sun::star; @@ -173,6 +177,52 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeExport) assertXPath(pXmlDoc, "//style:master-page/loext:theme/loext:color-table/loext:color", 12); } +CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testVideoSnapshot) +{ + // Execute ODP import: + OUString aURL = m_directories.getURLFromSrc(u"xmloff/qa/unit/data/video-snapshot.odp"); + getComponent() = loadFromDesktop(aURL, "com.sun.star.presentation.PresentationDocument"); + uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(getComponent(), + uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT(xDrawPagesSupplier.is()); + uno::Reference<drawing::XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages()); + uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT(xDrawPage.is()); + auto pUnoPage = dynamic_cast<SvxDrawPage*>(xDrawPage.get()); + SdrPage* pSdrPage = pUnoPage->GetSdrPage(); + auto pMedia = dynamic_cast<SdrMediaObj*>(pSdrPage->GetObj(0)); + + // Check that the preview was imported: + const avmedia::MediaItem& rItem = pMedia->getMediaProperties(); + const Graphic& rGraphic = rItem.getGraphic(); + CPPUNIT_ASSERT(!rGraphic.IsNone()); + + // Check that the crop was imported: + const text::GraphicCrop& rCrop = rItem.getCrop(); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), rCrop.Top); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), rCrop.Bottom); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1356), rCrop.Left); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1356), rCrop.Right); + + // Execute ODP export: + utl::TempFile aTempFile; + save("impress8", aTempFile); + + std::unique_ptr<SvStream> pStream = parseExportStream(aTempFile, "content.xml"); + xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get()); + // Check that the preview was exported: + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 0 + // - XPath '//draw:frame[@draw:style-name='gr1']/draw:image' number of nodes is incorrect + // i.e. the preview wasn't exported to ODP. + assertXPath(pXmlDoc, "//draw:frame[@draw:style-name='gr1']/draw:image", "href", + "Pictures/MediaPreview1.png"); + // Check that the crop was exported: + assertXPath(pXmlDoc, "//style:style[@style:name='gr1']/style:graphic-properties", "clip", + "rect(0cm, 1.356cm, 0cm, 1.356cm)"); +} + CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeImport) { // Given a document that has a master page with a theme associated: diff --git a/xmloff/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx index cd9c90efad24..6931c5684642 100644 --- a/xmloff/source/draw/shapeexport.cxx +++ b/xmloff/source/draw/shapeexport.cxx @@ -103,6 +103,7 @@ #include <tools/globname.hxx> #include <tools/helpers.hxx> #include <comphelper/diagnose_ex.hxx> +#include <vcl/graph.hxx> #include <xmloff/contextid.hxx> #include <xmloff/families.hxx> @@ -3400,7 +3401,7 @@ void XMLShapeExport::ImpExportMediaShape( mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, sMimeType ); // write plugin - SvXMLElementExport aPluginOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & XMLShapeExportFlags::NO_WS ), true); + auto pPluginOBJ = std::make_unique<SvXMLElementExport>(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & XMLShapeExportFlags::NO_WS ), true); // export parameters const OUString aFalseStr( "false" ), aTrueStr( "true" ); @@ -3450,6 +3451,57 @@ void XMLShapeExport::ImpExportMediaShape( delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true ); } + pPluginOBJ.reset(); + + uno::Reference<graphic::XGraphic> xGraphic; + xPropSet->getPropertyValue("Graphic") >>= xGraphic; + Graphic aGraphic(xGraphic); + if (!aGraphic.IsNone()) + { + // The media has a preview, export it. + uno::Reference<embed::XStorage> xPictureStorage; + uno::Reference<embed::XStorage> xStorage; + uno::Reference<io::XStream> xPictureStream; + OUString sPictureName; + xStorage.set(GetExport().GetTargetStorage(), uno::UNO_SET_THROW); + xPictureStorage.set( + xStorage->openStorageElement("Pictures", embed::ElementModes::READWRITE), + uno::UNO_SET_THROW); + sal_Int32 nIndex = 0; + while (true) + { + sPictureName = "MediaPreview" + OUString::number(++nIndex) + ".png"; + if (!xPictureStorage->hasByName(sPictureName)) + { + break; + } + } + + xPictureStream.set( + xPictureStorage->openStreamElement(sPictureName, ::embed::ElementModes::READWRITE), + uno::UNO_SET_THROW); + + uno::Reference<uno::XComponentContext> xContext = GetExport().getComponentContext(); + uno::Reference<graphic::XGraphicProvider> xProvider( + graphic::GraphicProvider::create(xContext)); + uno::Sequence<beans::PropertyValue> aArgs{ + comphelper::makePropertyValue("MimeType", OUString("image/png")), + comphelper::makePropertyValue("OutputStream", xPictureStream->getOutputStream()) + }; + xProvider->storeGraphic(xGraphic, aArgs); + if (xPictureStorage.is()) + { + uno::Reference<embed::XTransactedObject> xTrans(xPictureStorage, uno::UNO_QUERY); + if (xTrans.is()) + xTrans->commit(); + } + OUString sURL = "Pictures/" + sPictureName; + mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sURL); + mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE); + mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED); + mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD); + SvXMLElementExport aImageElem(GetExport(), XML_NAMESPACE_DRAW, XML_IMAGE, false, true); + } } void XMLShapeExport::ImpExport3DSceneShape( const uno::Reference< drawing::XShape >& xShape, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint) diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx index 1971c9b9f022..af0bfc1a7ef0 100644 --- a/xmloff/source/draw/ximpshap.cxx +++ b/xmloff/source/draw/ximpshap.cxx @@ -2918,6 +2918,12 @@ void SdXMLPluginShapeContext::startFastElement (sal_Int32 /*nElement*/, if( !mxShape.is() ) return; + if (mbMedia) + { + // The media may have a crop, apply it. + SetStyle(/*bSupportsStyle=*/false); + } + SetLayer(); if(bIsPresShape) @@ -3312,6 +3318,7 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLFrameShapeContext pShapeContext->setHyperlink( msHyperlink ); auto nToken = nElement & TOKEN_MASK; + bool bMedia = false; // Ignore gltf model if necessary and so the fallback image will be imported if( nToken == XML_PLUGIN ) { @@ -3321,10 +3328,15 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLFrameShapeContext mxImplContext = nullptr; return new SvXMLImportContext(GetImport()); } + else if (pPluginContext && pPluginContext->getMimeType() == "application/vnd.sun.star.media") + { + // The media may have a preview, import it. + bMedia = true; + } } mxImplContext = xContext; - mbSupportsReplacement = (nToken == XML_OBJECT ) || (nToken == XML_OBJECT_OLE); + mbSupportsReplacement = (nToken == XML_OBJECT ) || (nToken == XML_OBJECT_OLE) || bMedia; setSupportsMultipleContents(nToken == XML_IMAGE); if(getSupportsMultipleContents() && dynamic_cast< SdXMLGraphicObjectShapeContext* >(xContext.get())) |