[Libreoffice-commits] core.git: sd/qa sd/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Mar 4 13:32:38 UTC 2019


 sd/qa/unit/export-tests-ooxml2.cxx        |   37 +++++++++++++++
 sd/qa/unit/import-tests.cxx               |   27 -----------
 sd/source/filter/eppt/epptooxml.hxx       |    3 +
 sd/source/filter/eppt/pptx-animations.cxx |   47 ++++++++++++++++++-
 sd/source/filter/eppt/pptx-epptooxml.cxx  |   73 ++++++++++++++++++++++++++++++
 5 files changed, 158 insertions(+), 29 deletions(-)

New commits:
commit d98d3e2a0bc087ec9157e8e32e9f0ea4207d36e2
Author:     Mark Hung <marklh9 at gmail.com>
AuthorDate: Fri Mar 1 10:09:30 2019 +0800
Commit:     Mark Hung <marklh9 at gmail.com>
CommitDate: Mon Mar 4 14:32:15 2019 +0100

    tdf#44223: Export the audio of effects and transitions.
    
    This will allow to round trip the test case for the slide
    transition and the animation effect audio.
    
    Change-Id: Iac524e6bbcdb0a29491cfeba63121c845685fd11
    Reviewed-on: https://gerrit.libreoffice.org/68540
    Tested-by: Jenkins
    Reviewed-by: Mark Hung <marklh9 at gmail.com>

diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx
index ae60952752fc..eda6827a6869 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -198,6 +198,7 @@ public:
     void testTdf119118();
     void testTdf99213();
     void testPotxExport();
+    void testTdf44223();
 
     CPPUNIT_TEST_SUITE(SdOOXMLExportTest2);
 
@@ -278,6 +279,7 @@ public:
     CPPUNIT_TEST(testTdf119118);
     CPPUNIT_TEST(testTdf99213);
     CPPUNIT_TEST(testPotxExport);
+    CPPUNIT_TEST(testTdf44223);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -297,6 +299,7 @@ public:
             { "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" },
+            { "r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships" },
             { "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" },
@@ -2066,6 +2069,40 @@ void SdOOXMLExportTest2::testPotxExport()
     assertXPath(pContentTypes, "/ContentType:Types/ContentType:Override[@PartName='/ppt/presentation.xml']",
         "ContentType", "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml");
 }
+
+void SdOOXMLExportTest2::testTdf44223()
+{
+    utl::TempFile tempFile;
+    ::sd::DrawDocShellRef xDocShRef
+        = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf44223.pptx"), PPTX);
+    xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile);
+
+    std::shared_ptr<SvStream> const pStream1(parseExportStream(tempFile, "media/audio1.wav"));
+    CPPUNIT_ASSERT_EQUAL(sal_uInt64(11140), pStream1->remainingSize());
+
+    std::shared_ptr<SvStream> const pStream2(parseExportStream(tempFile, "media/audio2.wav"));
+    CPPUNIT_ASSERT_EQUAL(sal_uInt64(28074), pStream2->remainingSize());
+
+    xmlDocPtr pXmlContentType = parseExport(tempFile, "[Content_Types].xml");
+    assertXPath(pXmlContentType,
+                "/ContentType:Types/ContentType:Override[@PartName='/media/audio1.wav']",
+                "ContentType",
+                "audio/x-wav");
+
+    assertXPath(pXmlContentType,
+                "/ContentType:Types/ContentType:Override[@PartName='/media/audio2.wav']",
+                "ContentType",
+                "audio/x-wav");
+
+    xmlDocPtr pDoc1 = parseExport(tempFile, "ppt/slides/slide1.xml");
+    assertXPath(pDoc1 , "//p:audio/p:cMediaNode/p:tgtEl/p:sndTgt[@r:embed]", 1);
+
+    xmlDocPtr pDoc2 = parseExport(tempFile, "ppt/slides/slide2.xml");
+    assertXPath(pDoc2 , "//p:transition/p:sndAc/p:stSnd/p:snd[@r:embed]", 2);
+
+    xDocShRef->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest2);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 684dacbb7a84..44464e2559a2 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -44,8 +44,6 @@
 
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
 #include <com/sun/star/document/XEventsSupplier.hpp>
-#include <com/sun/star/document/XStorageBasedDocument.hpp>
-#include <com/sun/star/embed/XStorage.hpp>
 #include <com/sun/star/presentation/ClickAction.hpp>
 #include <com/sun/star/presentation/XPresentationPage.hpp>
 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
@@ -194,7 +192,6 @@ public:
     void testTdf123090();
     void testTdf120028();
     void testTdf120028b();
-    void testTdf44223();
     void testDescriptionImport();
     void testTdf83247();
     void testTdf47365();
@@ -282,7 +279,6 @@ public:
     CPPUNIT_TEST(testTdf123090);
     CPPUNIT_TEST(testTdf120028);
     CPPUNIT_TEST(testTdf120028b);
-    CPPUNIT_TEST(testTdf44223);
     CPPUNIT_TEST(testDescriptionImport);
     CPPUNIT_TEST(testTdf83247);
     CPPUNIT_TEST(testTdf47365);
@@ -2632,29 +2628,6 @@ void SdImportTest::testTdf120028b()
     xDocShRef->DoClose();
 }
 
-void SdImportTest::testTdf44223()
-{
-    ::sd::DrawDocShellRef xDocShRef
-        = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf44223.pptx"), PPTX);
-    uno::Reference<document::XStorageBasedDocument> xSBD(xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY);
-    CPPUNIT_ASSERT(xSBD.is());
-
-    uno::Reference<embed::XStorage> xStorage = xSBD->getDocumentStorage();
-    CPPUNIT_ASSERT(xStorage.is());
-
-    uno::Reference<container::XNameAccess> xNameAccess(xStorage, uno::UNO_QUERY);
-    CPPUNIT_ASSERT(xNameAccess.is());
-
-    uno::Reference<embed::XStorage> xStorage_2(xNameAccess->getByName("Media"), uno::UNO_QUERY);
-    CPPUNIT_ASSERT(xStorage_2.is());
-    uno::Reference< container::XNameAccess > xNameAccess_2(xStorage_2, uno::UNO_QUERY);
-
-    CPPUNIT_ASSERT(xNameAccess_2->hasByName("audio1.wav"));
-    CPPUNIT_ASSERT(xNameAccess_2->hasByName("audio2.wav"));
-
-    xDocShRef->DoClose();
-}
-
 void SdImportTest::testDescriptionImport()
 {
     sd::DrawDocShellRef xDocShRef
diff --git a/sd/source/filter/eppt/epptooxml.hxx b/sd/source/filter/eppt/epptooxml.hxx
index 5d6be2286af9..5791c0249b24 100644
--- a/sd/source/filter/eppt/epptooxml.hxx
+++ b/sd/source/filter/eppt/epptooxml.hxx
@@ -76,6 +76,9 @@ public:
 
     sal_Int32 GetShapeID(const css::uno::Reference<css::drawing::XShape>& rXShape);
     sal_Int32 GetNextAnimationNodeID();
+
+    void embedEffectAudio(const FSHelperPtr& pFS, const OUString& sUrl, OUString& sRelId, OUString& sName);
+
 private:
 
     virtual void ImplWriteSlide( sal_uInt32 nPageNum, sal_uInt32 nMasterNum, sal_uInt16 nMode,
diff --git a/sd/source/filter/eppt/pptx-animations.cxx b/sd/source/filter/eppt/pptx-animations.cxx
index 7e0967d19789..d484fcc91cb0 100644
--- a/sd/source/filter/eppt/pptx-animations.cxx
+++ b/sd/source/filter/eppt/pptx-animations.cxx
@@ -41,6 +41,7 @@
 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
 #include <com/sun/star/animations/XAnimateColor.hpp>
 #include <com/sun/star/animations/XCommand.hpp>
+#include <com/sun/star/animations/XAudio.hpp>
 #include <com/sun/star/animations/XTransitionFilter.hpp>
 #include <com/sun/star/animations/XIterateContainer.hpp>
 #include <com/sun/star/container/XEnumerationAccess.hpp>
@@ -393,6 +394,9 @@ sal_Int32 extractNodeType(const Reference<XAnimationNode>& rXNode)
         case AnimationNodeType::COMMAND:
             xmlNodeType = XML_cmd;
             break;
+        case AnimationNodeType::AUDIO:
+            xmlNodeType = XML_audio;
+            break;
         default:
             SAL_WARN("sd.eppt", "unhandled animation node: " << nType);
             break;
@@ -615,6 +619,7 @@ class PPTXAnimationExport
     void WriteAnimationNodeSeq();
     void WriteAnimationNodeEffect();
     void WriteAnimationNodeCommand();
+    void WriteAnimationNodeAudio();
     void WriteAnimationNodeCommonPropsStart();
     void WriteAnimationTarget(const Any& rTarget);
     void WriteAnimationCondList(const Any& rAny, sal_Int32 nToken);
@@ -1144,6 +1149,39 @@ void PPTXAnimationExport::WriteAnimationNodeCommand()
     mpFS->endElementNS(XML_p, XML_cmd);
 }
 
+void PPTXAnimationExport::WriteAnimationNodeAudio()
+{
+    SAL_INFO("sd.eppt", "write animation node audio");
+    Reference<XAudio> xAudio(getCurrentNode(), UNO_QUERY);
+
+    OUString sUrl;
+    OUString sRelId;
+    OUString sName;
+
+    if (!(xAudio.is() && (xAudio->getSource() >>= sUrl) && !sUrl.isEmpty()
+          && sUrl.endsWithIgnoreAsciiCase(".wav")))
+        return;
+
+    mrPowerPointExport.embedEffectAudio(mpFS, sUrl, sRelId, sName);
+
+    mpFS->startElementNS(XML_p, XML_audio, FSEND);
+    mpFS->startElementNS(XML_p, XML_cMediaNode, FSEND);
+
+    mpFS->startElementNS(XML_p, XML_cTn, FSEND);
+    WriteAnimationCondList(mpContext->getCondition(true), XML_stCondLst);
+    WriteAnimationCondList(mpContext->getCondition(false), XML_endCondLst);
+    mpFS->endElementNS(XML_p, XML_cTn);
+
+    mpFS->startElementNS(XML_p, XML_tgtEl, FSEND);
+    mpFS->singleElementNS(XML_p, XML_sndTgt, FSNS(XML_r, XML_embed),
+                          sRelId.isEmpty() ? nullptr : USS(sRelId), XML_name,
+                          sUrl.isEmpty() ? nullptr : USS(sName), FSEND);
+    mpFS->endElementNS(XML_p, XML_tgtEl);
+
+    mpFS->endElementNS(XML_p, XML_cMediaNode);
+    mpFS->endElementNS(XML_p, XML_audio);
+}
+
 void PPTXAnimationExport::WriteAnimationNode(const NodeContextPtr& pContext)
 {
     const NodeContext* pSavedContext = mpContext;
@@ -1178,6 +1216,9 @@ void PPTXAnimationExport::WriteAnimationNode(const NodeContextPtr& pContext)
         case XML_cmd:
             WriteAnimationNodeCommand();
             break;
+        case XML_audio:
+            WriteAnimationNodeAudio();
+            break;
         default:
             SAL_WARN("sd.eppt", "export ooxml node type: " << xmlNodeType);
             break;
@@ -1278,8 +1319,10 @@ void NodeContext::initValid(bool bHasValidChild, bool bIsIterateChild)
     }
     else if (nType == AnimationNodeType::AUDIO)
     {
-        SAL_WARN("sd.eppt", "Export AUDIO node is not supported yet.");
-        mbValid = false;
+        Reference<XAudio> xAudio(mxNode, UNO_QUERY);
+        OUString sURL;
+        mbValid
+            = xAudio.is() && (xAudio->getSource() >>= sURL) && sURL.endsWithIgnoreAsciiCase(".wav");
     }
     else
     {
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx
index b91c265b90bd..2d244f2fb523 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -115,6 +115,21 @@ public:
     bool WritePlaceholder(const Reference< XShape >& xShape, PlaceholderType ePlaceholder, bool bMaster);
 };
 
+
+namespace
+{
+void WriteSndAc(const FSHelperPtr& pFS, const OUString& sSoundRelId, const OUString& sSoundName)
+{
+        pFS->startElementNS(XML_p, XML_sndAc, FSEND);
+        pFS->startElementNS(XML_p, XML_stSnd, FSEND);
+        pFS->singleElementNS(XML_p, XML_snd,
+                FSNS(XML_r, XML_embed), sSoundRelId.isEmpty() ? nullptr : USS(sSoundRelId),
+                XML_name, sSoundName.isEmpty() ? nullptr : USS(sSoundName), FSEND);
+        pFS->endElement(FSNS(XML_p, XML_stSnd));
+        pFS->endElement(FSNS(XML_p, XML_sndAc));
+}
+}
+
 }
 }
 
@@ -546,6 +561,10 @@ void PowerPointExport::WriteTransition(const FSHelperPtr& pFS)
     sal_Int8 nPPTTransitionType = 0;
     sal_uInt8 nDirection = 0;
 
+    OUString sSoundUrl;
+    OUString sSoundRelId;
+    OUString sSoundName;
+
     if (ImplGetPropertyValue(mXPagePropSet, "TransitionType") && (mAny >>= nTransitionType) &&
             ImplGetPropertyValue(mXPagePropSet, "TransitionSubtype") && (mAny >>= nTransitionSubtype))
         nPPTTransitionType = GetTransition(nTransitionType, nTransitionSubtype, eFadeEffect, nDirection);
@@ -553,6 +572,9 @@ void PowerPointExport::WriteTransition(const FSHelperPtr& pFS)
     if (!nPPTTransitionType && eFadeEffect != FadeEffect_NONE)
         nPPTTransitionType = GetTransition(eFadeEffect, nDirection);
 
+    if (ImplGetPropertyValue(mXPagePropSet, "Sound") && (mAny >>= sSoundUrl))
+        embedEffectAudio(pFS, sSoundUrl, sSoundRelId, sSoundName);
+
     bool bOOXmlSpecificTransition = false;
 
     sal_Int32 nTransition = 0;
@@ -866,6 +888,9 @@ void PowerPointExport::WriteTransition(const FSHelperPtr& pFS)
                 FSEND);
         }
 
+        if (!sSoundRelId.isEmpty())
+            WriteSndAc(pFS, sSoundRelId, sSoundName);
+
         pFS->endElement(FSNS(XML_p, XML_transition));
 
         pFS->endElement(FSNS(XML_mc, XML_Choice));
@@ -887,6 +912,9 @@ void PowerPointExport::WriteTransition(const FSHelperPtr& pFS)
                              FSEND);
     }
 
+    if (!sSoundRelId.isEmpty())
+        WriteSndAc(pFS, sSoundRelId, sSoundName);
+
     pFS->endElementNS(XML_p, XML_transition);
 
     if (nTransition14 || pPresetTransition || isTransitionDurationSet)
@@ -1935,6 +1963,51 @@ void PowerPointExport::WriteNotesMaster()
     SAL_INFO("sd.eppt", "----------------");
 }
 
+void PowerPointExport::embedEffectAudio(const FSHelperPtr& pFS, const OUString& sUrl, OUString& sRelId, OUString& sName)
+{
+    comphelper::LifecycleProxy aProxy;
+
+    if (!sUrl.endsWithIgnoreAsciiCase(".wav"))
+        return;
+
+    uno::Reference<io::XInputStream> xAudioStream;
+    if (sUrl.startsWith("vnd.sun.star.Package:"))
+    {
+        uno::Reference<document::XStorageBasedDocument> xStorageBasedDocument(getModel(), uno::UNO_QUERY);
+        if (!xStorageBasedDocument.is())
+            return;
+
+        uno::Reference<embed::XStorage> xDocumentStorage(xStorageBasedDocument->getDocumentStorage(), uno::UNO_QUERY);
+        if (!xDocumentStorage.is())
+            return;
+
+        uno::Reference<io::XStream> xStream = comphelper::OStorageHelper::GetStreamAtPackageURL(xDocumentStorage, sUrl,
+                                                    css::embed::ElementModes::READ, aProxy);
+
+        if (xStream.is())
+            xAudioStream = xStream->getInputStream();
+    }
+    else
+        xAudioStream = comphelper::OStorageHelper::GetInputStreamFromURL(sUrl, getComponentContext());
+
+    if (!xAudioStream.is())
+        return;
+
+    int nLastSlash = sUrl.lastIndexOf('/');
+    sName = sUrl.copy(nLastSlash >= 0 ? nLastSlash + 1 : 0);
+
+    OUString sPath = OUStringBuffer().append("/media/")
+                                     .append(sName)
+                                     .makeStringAndClear();
+
+    sRelId = addRelation(pFS->getOutputStream(),
+                        oox::getRelationship(Relationship::AUDIO), sPath);
+
+    uno::Reference<io::XOutputStream> xOutputStream = openFragmentStream(sPath, "audio/x-wav");
+
+    comphelper::OStorageHelper::CopyInputToOutput(xAudioStream, xOutputStream);
+}
+
 sal_Int32 PowerPointExport::GetShapeID(const Reference<XShape>& rXShape)
 {
     return ShapeExport::GetShapeID(rXShape, &maShapeMap);


More information about the Libreoffice-commits mailing list