From 50f8e0e479e70fca3620da192e5a2cc4ca12bc2c Mon Sep 17 00:00:00 2001 From: Jan Holesovsky Date: Tue, 5 Sep 2017 16:53:14 +0200 Subject: tdf#106867: Export videos in PPTX. Contains also: tdf#106867: Implement pptx export of AnimationNodeType::COMMAND. tdf#106867: Import target for commands in PPTX. tdf#106867: Write also the extended markup to fully support embedded videos. tdf#106867: Unit test for the export of embedded videos. Change-Id: I7f4f389a72aa7ecef65d87f07bb69ba8f3374a14 Reviewed-on: https://gerrit.libreoffice.org/42017 Reviewed-by: Miklos Vajna Tested-by: Miklos Vajna --- sd/qa/unit/data/pptx/tdf106867.pptx | Bin 0 -> 52203 bytes sd/qa/unit/export-tests-ooxml2.cxx | 33 ++++++++++++++++++ sd/source/filter/eppt/epptooxml.hxx | 1 + sd/source/filter/eppt/pptx-epptooxml.cxx | 56 +++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+) create mode 100644 sd/qa/unit/data/pptx/tdf106867.pptx (limited to 'sd') diff --git a/sd/qa/unit/data/pptx/tdf106867.pptx b/sd/qa/unit/data/pptx/tdf106867.pptx new file mode 100644 index 000000000000..5bf16d690ef2 Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf106867.pptx differ diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx index 817cad398a13..5586564a33e5 100644 --- a/sd/qa/unit/export-tests-ooxml2.cxx +++ b/sd/qa/unit/export-tests-ooxml2.cxx @@ -105,6 +105,7 @@ public: void testTdf59046(); void testTdf105739(); void testTdf111518(); + void testTdf106867(); CPPUNIT_TEST_SUITE(SdOOXMLExportTest2); @@ -133,6 +134,7 @@ public: CPPUNIT_TEST(testTdf59046); CPPUNIT_TEST(testTdf105739); CPPUNIT_TEST(testTdf111518); + CPPUNIT_TEST(testTdf106867); CPPUNIT_TEST_SUITE_END(); @@ -151,6 +153,7 @@ public: { "pic", "http://schemas.openxmlformats.org/drawingml/2006/picture" }, { "wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" }, { "p", "http://schemas.openxmlformats.org/presentationml/2006/main" }, + { "p14", "http://schemas.microsoft.com/office/powerpoint/2010/main" }, { "w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main" }, { "a14", "http://schemas.microsoft.com/office/drawing/2010/main" }, { "wps", "http://schemas.microsoft.com/office/word/2010/wordprocessingShape" }, @@ -807,6 +810,36 @@ void SdOOXMLExportTest2::testTdf111518() "M -3.54167E-6 -4.81481E-6 L 0.39037 -0.00069"); } +void SdOOXMLExportTest2::testTdf106867() +{ + ::sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf106867.pptx"), PPTX); + utl::TempFile tempFile; + xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile); + + const SdrPage *pPage = GetPage(1, xDocShRef.get()); + + // first check that we have the media object + const SdrMediaObj* pMediaObj = dynamic_cast(pPage->GetObj(2)); + CPPUNIT_ASSERT_MESSAGE("no media object", pMediaObj != nullptr); + CPPUNIT_ASSERT_EQUAL(OUString("vnd.sun.star.Package:ppt/media/media1.avi"), pMediaObj->getURL()); + + xDocShRef->DoClose(); + + // additional checks of the output file + uno::Reference xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), tempFile.GetURL()); + // check that the document contains the video stream + CPPUNIT_ASSERT(xNameAccess->hasByName("ppt/media/media1.avi")); + + // both the ooxml and the extended markup + xmlDocPtr pXmlDocContent = parseExport(tempFile, "ppt/slides/slide1.xml"); + assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:pic/p:nvPicPr/p:nvPr/a:videoFile"); + assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:pic/p:nvPicPr/p:nvPr/p:extLst/p:ext/p14:media"); + + // target the shape with the video in the command + assertXPath(pXmlDocContent, "/p:sld/p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:cmd/p:cBhvr/p:tgtEl/p:spTgt", + "spid", "42"); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest2); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sd/source/filter/eppt/epptooxml.hxx b/sd/source/filter/eppt/epptooxml.hxx index 1134daf6cb7a..ebfe5d345813 100644 --- a/sd/source/filter/eppt/epptooxml.hxx +++ b/sd/source/filter/eppt/epptooxml.hxx @@ -108,6 +108,7 @@ protected: void WriteAnimationNodeAnimateInside( const ::sax_fastparser::FSHelperPtr& pFS, const css::uno::Reference< css::animations::XAnimationNode >& rXNode, bool bMainSeqChild, bool bSimple ); void WriteAnimationNodeSeq( const ::sax_fastparser::FSHelperPtr& pFS, const css::uno::Reference< css::animations::XAnimationNode >& rXNode, sal_Int32 nXmlNodeType, bool bMainSeqChild ); void WriteAnimationNodeEffect( const ::sax_fastparser::FSHelperPtr& pFS, const css::uno::Reference< css::animations::XAnimationNode >& rXNode, sal_Int32 nXmlNodeType, bool bMainSeqChild ); + void WriteAnimationNodeCommand(const ::sax_fastparser::FSHelperPtr& pFS, const css::uno::Reference< css::animations::XAnimationNode >& rXNode, sal_Int32 nXmlNodeType, bool bMainSeqChild ); void WriteAnimationNodeCommonPropsStart( const ::sax_fastparser::FSHelperPtr& pFS, const css::uno::Reference< css::animations::XAnimationNode >& rXNode, bool bSingle, bool bMainSeqChild ); static void WriteAnimationProperty( const ::sax_fastparser::FSHelperPtr& pFS, const css::uno::Any& rAny ); void WriteAnimationTarget( const ::sax_fastparser::FSHelperPtr& pFS, const css::uno::Any& rTarget ); diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx index 383706809c89..d4d8fe6908b4 100644 --- a/sd/source/filter/eppt/pptx-epptooxml.cxx +++ b/sd/source/filter/eppt/pptx-epptooxml.cxx @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,7 @@ #include #include #include +#include #include #include @@ -309,6 +311,8 @@ ShapeExport& PowerPointShapeExport::WriteUnknownShape( const Reference< XShape > if( !WritePlaceholder( xShape, Subtitle, mbMaster ) ) ShapeExport::WriteTextShape( xShape ); } + else + SAL_WARN("sd.eppt", "unknown shape not handled: " << USS(sShapeType)); return *this; } @@ -1061,6 +1065,7 @@ void PowerPointExport::WriteAnimationCondition( const FSHelperPtr& pFS, Any& rAn double fDelay = 0; Timing eTiming; Event aEvent; + Reference xShape; const char* pDelay = nullptr; const char* pEvent = nullptr; @@ -1127,6 +1132,15 @@ void PowerPointExport::WriteAnimationCondition( const FSHelperPtr& pFS, Any& rAn SAL_INFO("sd.eppt", "event offset timing: " << eTiming); } } + else if (rAny >>= xShape) + { + SAL_INFO("sd.eppt", "Got the xShape: " << xShape->getShapeType()); + if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape" || xShape->getShapeType() == "com.sun.star.presentation.MediaShape") + { + // write the default + bHasFDelay = true; + } + } WriteAnimationCondition( pFS, pDelay, pEvent, fDelay, bHasFDelay ); } @@ -1358,6 +1372,41 @@ void PowerPointExport::WriteAnimationNodeEffect( const FSHelperPtr& pFS, const R } } +void PowerPointExport::WriteAnimationNodeCommand(const FSHelperPtr& pFS, const Reference< XAnimationNode >& rXNode, sal_Int32, bool bMainSeqChild) +{ + SAL_INFO("sd.eppt", "write animation node COMMAND"); + Reference xCommand(rXNode, UNO_QUERY); + if (xCommand.is()) + { + const char* pType = "call"; + const char* pCommand = nullptr; + switch (xCommand->getCommand()) + { + case EffectCommands::VERB: pType = "verb"; pCommand = "1"; /* FIXME hardcoded viewing */ break; + case EffectCommands::PLAY: pCommand = "play"; break; + case EffectCommands::TOGGLEPAUSE: pCommand = "togglePause"; break; + case EffectCommands::STOP: pCommand = "stop"; break; + default: + SAL_WARN("sd.eppt", "unknown command: " << xCommand->getCommand()); + break; + } + + pFS->startElementNS(XML_p, XML_cmd, + XML_type, pType, + XML_cmd, pCommand, + FSEND); + + WriteAnimationNodeAnimateInside(pFS, rXNode, bMainSeqChild, false); + pFS->startElementNS(XML_p, XML_cBhvr, + FSEND); + WriteAnimationNodeCommonPropsStart(pFS, rXNode, true, bMainSeqChild); + WriteAnimationTarget(pFS, xCommand->getTarget()); + pFS->endElementNS(XML_p, XML_cBhvr); + + pFS->endElementNS(XML_p, XML_cmd); + } +} + void PowerPointExport::WriteAnimationNode( const FSHelperPtr& pFS, const Reference< XAnimationNode >& rXNode, bool bMainSeqChild ) { SAL_INFO("sd.eppt", "export node type: " << rXNode->getType()); @@ -1388,6 +1437,13 @@ void PowerPointExport::WriteAnimationNode( const FSHelperPtr& pFS, const Referen xmlNodeType = XML_animEffect; pMethod = &PowerPointExport::WriteAnimationNodeEffect; break; + case AnimationNodeType::COMMAND: + xmlNodeType = XML_cmd; + pMethod = &PowerPointExport::WriteAnimationNodeCommand; + break; + default: + SAL_WARN("sd.eppt", "unhandled: " << rXNode->getType()); + break; } if( pMethod ) { -- cgit v1.2.3